J'essaie de résoudre un problème, que j'ai trouvé sur le site Web https://open.kattis.com/problems/coast. La version du problème est que, pour une carte donnée du paysage, je devrais imprimer la longueur du littoral (sans les îles intérieures). Mon idée était de résoudre ce problème en ajoutant un calque supplémentaire, puis en démarrant DFS, afin que l'algorithme parcourt toutes les cases possibles de la carte, puis surveille chaque tuile, combien de bordures se trouvent autour de la tuile. Cependant, pour une entrée spécifique, mon algorithme ne fonctionne pas. Lorsque j'ai soumis la solution sur ce site (open.kattis), il est dit que mon programme donne une mauvaise réponse dans 9 des 26 tests (les 8 précédents étaient corrects), mais sans autre explication. Est-ce que quelqu'un peut regarder mon programme, et dites-moi, pourquoi est-ce mauvais? Où ai-je fait erreur? MerciProblème avec DFS dans la résolution de la longueur du littoral
#include <iostream>
#include <stack>
#include <sstream>
using namespace std;
int main() {
string line;
getline(cin, line);
int rows = 0;
int columns = 0;
stringstream stream(line);
stream >> rows;
stream >> columns;
int map[rows][columns];
for (int i = 0; i < rows; i++) {
getline(cin, line);
for (int j = 0; j < columns; j++) {
map[i][j] = line[j] - 48;
}
}
//parsed landscape into 2d array
// int rows = 5;
// int columns = 6;
// int map[rows][columns] = {
// {0, 1, 1, 1, 1, 0,},
// {0, 1, 0, 1, 1, 0,},
// {1, 1, 1, 0, 0, 0,},
// {0, 0, 0, 0, 1, 0,},
// {0, 0, 0, 0, 0, 0,},
// };
int bigMap[rows+2][columns+2];
bool visited[rows+2][columns+2];
//create bigger map, so DFS can start from corner and assume
//that there is water around everywhere
//also initialize array visited for DFS
//add 2 new rows, before and after existing one
for (int i = 0; i < columns+2; i++) {
bigMap[0][i] = 0;
bigMap[rows + 1][i] = 0;
visited[0][i] = false;
visited[rows + 1][i] = false;
}
//add 2 new columns, before and after existing
//copy original map to new one
for (int i = 0; i < rows; i++) {
bigMap[i+1][0] = 0;
bigMap[i+1][columns + 1] = 0;
visited[i+1][0] = false;
visited[i+1][columns + 1] = false;
for (int j = 0; j < columns; j++) {
bigMap[i+1][j+1] = map[i][j];
visited[i+1][j+1] = false;
}
}
rows += 2;
columns += 2;
//starting DFS
int x = 0, y = 0;
//visited[x][y] = true; <-- edit
pair <int, int> coordinates;
coordinates.first = x;
coordinates.second = y;
stack<pair <int, int> > st;
//first vertex in stack
st.push(coordinates);
//total sum of borders
int borders = 0;
while(!st.empty()) {
//check coordinates in each round
x = st.top().first;
y = st.top().second;
//navigate to new vertex (only if new vertex wasn't visited (visited[x][y] == 0) and only
//if there is water (bigMap[x][y] == 0) and check if new vertex is still in the map
//if there is no possible vertex, then we reached the end so then pop the vertex and
//look in another way
if (visited[x][y+1] == 0 && bigMap[x][y+1] == 0 && y + 1 < columns) {
y++;
coordinates.second = y;
st.push(coordinates);
} else {
if (visited[x+1][y] == 0 && bigMap[x+1][y] == 0 && x + 1 < rows) {
x++;
coordinates.first = x;
st.push(coordinates);
} else {
if (visited[x][y-1] == 0 && bigMap[x][y-1] == 0 && y > 0) {
y--;
coordinates.second = y;
st.push(coordinates);
} else {
if (visited[x-1][y] == 0 && bigMap[x-1][y] == 0 && x > 0) {
x--;
coordinates.first = x;
st.push(coordinates);
} else {
st.pop();
continue;
}
}
}
}
//visited new vertex, so look around him and count borders
visited[x][y] = true;
if (bigMap[x][y+1] == 1 && y + 1 < columns) borders++;
if (bigMap[x+1][y] == 1 && x + 1< rows) borders++;
if (bigMap[x][y-1] == 1 && y > 0) borders++;
if (bigMap[x-1][y] == 1 && x > 0) borders++;
}
cout << borders << endl;
return 0;
les tableaux de longueur variable ne sont pas standard C++. Il est possible que leur test utilise un compilateur qui donne un avertissement, puis n'alloue pas de mémoire pour le tableau, ce qui conduit à un comportement indéfini. Pouvez-vous l'essayer sans utiliser de tableaux de longueur variable (c.-à-d. Juste mettre les trois tableaux 'map',' bigmap' et 'visited' à quelque chose comme 1024x1024 - vous n'avez pas besoin de changer quoi que ce soit d'autre que les déclarations) –
Je pense, que c'est un problème, parce que 9 sur 26 passent le test. donc, s'il y aura un problème avec le compilateur, il échouera dans le premier test, pas dans le 9ème, ou comme après 1 bugfix dans la 11ème. il y a aussi le temps et la limite de mémoire, donc si je travaille juste avec 1024^2 tableau, je suis inquiet que l'alg. ne le fera pas à travers les limites. mais merci pour votre idée :) –
La limite de temps ne sera pas affectée par la taille des tableaux car vous accéderez toujours au même nombre d'entrées de tableau, le reste sera inutilisé. La limite de mémoire est de 1024 Mo ce qui vous donne assez pour 250 tableaux de 1024x1024 entiers de 32 bits. Donc 3 ne devrait pas poser de problème. –