一年前的2017.12.02,头次参加了程序设计类的比赛,学校的ACM校赛,在低年级组全是水题的情况下只做上两道题(其中一个还是hello world),其中有一道题只有1AC(by LuckyT99),由于AC数量过少,赛完很长一段时间对这道题有一种恐惧的心态,导致不敢去补题(还不是只挑软柿子捏,哪个简单做哪个?)
一年后的今天(11.18),低年级组摸底热身赛这道题再次出现,学弟问我这道题怎么做,才终于正视这道题,以一年后的水平,居然做了两个小时(+3)才AC,自己真的菜得要命啊!
传送门:
http://acm.hhu.edu.cn/problem.php?cid=1015&pid=2
思路:
简单的搜索,根据题意模拟动作即可。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
static const int maxn = 100010;
static const double eps = 1e-6;
static const int INF = 0x3f3f3f3f;
static const double pi = acos(-1);
static const int mod = (int)1e9 + 7;
void redirect(){
#ifdef LOCAL
freopen("test.txt","r",stdin);
#endif
}
char maze[15][15];
const int dx[] = {0,1,0,-1};
const int dy[] = {1,0,-1,0};
int sx,sy,n,m,d;
bool flag = true;
bool vis[15][15][4];
void dfs(int x,int y,int dir){
if(x <= 0 || y <= 0 || x >= n+1 || y >= m+1 || maze[x][y] == 'X')return;
if(flag == false || vis[x][y][dir] == true)return;
vis[x][y][dir] = true;
if(maze[x][y] == 'U'){flag = false;return;}
int tx = x+dx[dir],ty = y+dy[dir];
if(maze[tx][ty] == 'X')
for(int i = 1;i <= 3;i++)d = (dir+i)%4,dfs(x+dx[d],y+dy[d],d);
else dfs(tx,ty,dir);
}
int main(){
redirect();
scanf("%d %d",&n,&m);
for(int i = 1;i <= n;i++){
scanf("%s",maze[i]+1);
for(int j = 1;j <= m;j++)
if(maze[i][j] == 'K')sx = i,sy = j;
}
for(int i = 0;i < 4;i++)
dfs(sx,sy,i);
if(flag)puts("Safe");
else puts("Dangerous");
return 0;
}
坑点:
在类似XKX的情况中,WA的写法是遇到X就dfs其他三个方向,而忘记判断是否合法,导致X被当作O走了,在
4 3
OUO
OXO
XKX
OXO
这组数据中,U被视为可达,导致WA。
总结:
在写dfs的时候,把判断是否合法尽量写在函数终止条件(函数头部),而不要在循环内,否则就可能产生这种问题。