您的位置:首页 > 其它

CodeForces 540C--自带标记的四方向搜索

2016-07-27 11:02 423 查看
题意:

给一个 n 行,m 列的字符矩阵,*表示完整的冰块,X表示断裂的冰块,*踩一下变成X,X踩一下就断裂,之后给出两个确定的点,在

保证冰块不发生断裂的情况下,问能否从一个点走到另一个点,并将到达的那个点的冰块踩碎,不能再原地踏步。

输入:

4 6
X...XX
...XX.
.X..X.
......
1 6
2 2

5 4
.X..
...X
X.X.
....
.XX.
5 3
1 1

输出:

YES

NO

分析:

一个自带状态的四方向的搜索,我们要保证访问*的点不访问X的点,这一点类似贪心,访问之后,该点就变成了X,如果到达的那一

点可以变成X,则表示可以到达。

代码:

自带状态的dfs

#include<bits/stdc++.h>
using namespace std;

char c[505][505];
int r1,c1,r2,c2;
int n,m;
int dr[]= {1,0,-1,0};
int dc[]= {0,1,0,-1};
bool dfs(int rr,int cc)
{
if(rr<0||rr>=n||cc<0||cc>=m)
return false;
if(c[rr][cc]=='X'&&rr==r2&&cc==c2) //可到达
return true;
else if(c[rr][cc]=='X') //保证只访问"."
return false;
c[rr][cc]='X'; //访问过
for(int i=0; i<4; i++)
{
if(dfs(rr+dr[i],cc+dc[i])) //可递归
return true;
}
return false;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
cin >>c[i][j];
}
}
scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
r1--;
c1--;
r2--;
c2--; //给出的坐标和矩阵中的位置不对应
printf("(%d,%d),(%d,%d)\n",r1,c1,r2,c2);
int f=0;
for(int i=0; i<4; i++)
{
if(dfs(r1+dr[i],c1+dc[i]))
f=1;
}
if(f)
printf("YES\n");
else
printf("NO\n");
return 0;
}

自带状态的bfs:

#include <bits/stdc++.h>
using namespace std;

int n,m,r1,c1,r2,c2;
int dr[]= {1,0,-1,0};
int dc[]= {0,1,0,-1};
char c[505][505];

bool bfs()
{
queue <int> qx,qy;
qx.push(r1);
qy.push(c1);
while(!qx.empty())
{
int rr=qx.front();
int cc=qy.front();
qx.pop();
qy.pop();
for(int i=0; i<4; i++)
{
int tmpr=rr+dr[i];
int tmpc=cc+dc[i];
if(tmpr==r2&&tmpc==c2&&c[tmpr][tmpc]=='X')
return true;
if(tmpr>=1&&tmpr<=n&&tmpc>=1&&tmpc<=m&&c[tmpr][tmpc]=='.')
{
c[tmpr][tmpc]='X';
qx.push(tmpr);
qy.push(tmpc);
}
}
}
return false;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
cin >>c[i][j];
}
}
scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
if(bfs())
printf("YES\n");
else
printf("NO\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: