我试图解决一个问题,我在网站https://open.kattis.com/problems/coast找到了这个问题。 Tl; dr版本的问题是,对于给定的景观地图,我应该打印出海岸线的长度(没有内岛)。
我的想法是,通过添加额外的图层然后启动DFS来解决这个问题,因此算法将遍历地图中的每个可能的图块,然后在每个图块上观察图块周围有多少个边框。
但是,对于特定输入,我的算法不起作用。当我在这个网站(open.kattis)上提交解决方案时,它说,我的程序在26个测试中的第9个中给出了错误的答案(前8个测试没问题),但没有任何进一步的解释。
有人可以看看我的节目,然后说我,为什么不好?我哪里弄错了?感谢
#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;
答案 0 :(得分:0)
我认为{1,0,0,0},{0,1,1,0},{0,1,1,0},{0,0,0,0}会失败。这是因为由于顶点0,0的设置visited = true,因此无法完成漫游。将它设为false为0,0而不是改进的东西。希望它有所帮助。
答案 1 :(得分:0)
问题是您每次在循环周围重复使用变量coordinates
而不将其设置为正确的值。您的if
测试级联假设coordinates
设置为当前位置。只有在降级dfs时才会出现这种情况。一旦你再次开始提升,coordinate
将指向错误的位置。
简单解决方案,添加
coordinates = st.top();
在你的循环顶部。
以下是目前出错的示例地图。
5 6
000000
011100
001010
000100
000000
答案应该是14,但是目前你得到18,因为程序到达第3行第4列的湖泊。
要检查它是否正在执行此操作,请在循环的末尾添加一个调试行,以便添加边框。
cout << "adding " << x << " " << y << "\n";
然后,您可以验证该程序是否正在考虑它不应该使用的任何位置。