Ошибка в задаче, поиск клада
Приветсвую, есть задача: дана карта (в виде двумернного массива). На карте есть 3 подсказки, сколько шагов по горизонтали и вертикали нужно сделать чтобы найти клад.
Решаю следующим, найти все возможные маршруты на карте. Места в массиве с цифрой 0, должный граничить с 3-мя 1. Пример: 10123 | 01000
Клад находится в индексах [0][1] первая линейка, 2 столбец
Если таких мест больше чем 1, результат cout << “Нехватает информации»;
Код отправляеться на сервер, проходит 4 теста из 5-ти, но в одном ошибается. Входных данных у меня нет, поэтому немогу понять где ошибка.
int main() {
int n, m; // размер двумеррного массива n*m
int contains = 0; // что содержит элемент массива
cin >> n >> m;
// **** Создать двумернный массив *****
int** map = new int* [n];
for (int i = 0; i <= n; i++) {
map[i] = new int[m];
}
// *** Заполнить массив * *****
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> contains;
map[i][j] = contains;
}
}
// *** Заполнить все возможнные шаги
for (int k = 0; k < 100; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (map[i][j] > 1) {
contains = map[i][j];
if (j > 0 && map[i][j - 1] < contains - 1)
map[i][j - 1] = contains - 1;
if (i > 0 && contains - 1 > map[i - 1][j])
map[i - 1][j] = contains - 1;
if (j < m && map[i][j + 1] < contains - 1)
map[i][j + 1] = contains - 1;
if (i < n && contains - 1 > map[i + 1][j])
map[i + 1][j] = contains - 1;
}
}
}
}
// Подсчёт соседей
int kaimyn_kiek = 0;
int vietu = 0;
int X_cords;
int Y_cords;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
kaimyn_kiek = 0;
if (map[i][j] == 0) {
if (j > 0 && map[i][j - 1] == 1)
kaimyn_kiek++;
if (i > 0 && map[i - 1][j] == 1)
kaimyn_kiek++;
if (j < m && map[i][j + 1] == 1)
kaimyn_kiek++;
if (i < n && map[i + 1][j] == 1)
kaimyn_kiek++;
if (kaimyn_kiek >= 3) {
kaimyn_kiek = 0;
X_cords = i + 1;
Y_cords = j + 1;
vietu++;
}
}
}
}
// ** Результат
if (vietu == 1)
cout << X_cords << " " << Y_cords;
else
cout << "Нехватает информации";
return 0;
}
Ответы (2 шт):
Так у тебя в самом начале ошибка.
int** map = new int* [n]; // n - Это размер всего массива (1, 228 и т.д)
// for (int i = 0; i <= n; i++) -- '<=' Так НЕ ПРАВИЛЬНО!
/*
Вот тут ты написал <=, но отсчёт начинается от 0 и до конца массива,
т.е в твоём случае номер последнего элемента будет (n - 1).
Используя '<=' в данной ситуации ты выходишь за рамки массива,
это не есть хорошо!
Это легко запомнить, т.к. массив сам по себе это указатель
'pointer[offset]', где `pointer` - указатель, а offset - смещение.
Говорив poiner[0] ты говоришь *(pointer + 0), а pointer[1] -
*(pointer + 1).
*/
for (int i{}; i < n; i++) // -- '<' Вот так правильно!
for (int i{}; i <= n - 1; i++) // Вот так тоже правильно, но зачем?
for (int i{ n - 1 }; i >= 0; i--) // Тоже самое, что и выше, только наоборот
ИМХО, лучше всего используй std::vector, лично мне кажется он в данной ситуации больше подходит. Посуди сам:
/* Вместо вот этого */
int n, m;
int** map = new int* [n];
/* Вот это */
std::vector<std::vector<int>> vecMap{};
/* Тем более безопасней */
/* Вместо */
for (int i{}; i < n; i++)
{
// ...
}
/* Вот это */
for (auto &vec_map : vecMap)
{
vec_map[0][2] = 1991;
// ...
}
Подробнее про std::vector можешь прочитать вот тут - vector - cplusplus.com
Ошибка была в алгоритме решения задачи, однако во многих циклах также был выход за пределы массива, что не есть хорошо.
Дело в том, что первый алгоритм ошибался, потому-что возможный путь от одной точки считался как за два разных. Как решил:
- Сохраняем в двухмерный массив первичные данные.
- Для каждой подсказки создаётся отдельный двухмерный массив, на котором просчитывается возможный маршрут. Первичный же массив заполняем нулями.
- Конец маршрута для каждой подсказки отмечается в первичном массиве, место где 3 точки пересекаются и есть ответ, в случае если таких точек больше или нет, ответ: недостаточно данных.