两只牛逃跑到了森林里。Farmer John 开始用他的专家技术追捕这两头牛。你的任务是模拟他们的行为(牛和 John)。
追击在 10 \times 1010×10 的平面网格内进行。一个格子可以是:一个障碍物,两头牛(它们总在一起),或者 Farmer John。两头牛和 Farmer John 可以在同一个格子内(当他们相遇时),但是他们都不能进入有障碍的格子。
一个格子可以是:
. 空地;
- 障碍物;
C 两头牛;
F Farmer John。
这里有一个地图的例子:
……
……
………
…
….F…
……
……
…C…
….…
..…
牛在地图里以固定的方式游荡。每分钟,它们可以向前移动或是转弯。如果前方无障碍(地图边沿也是障碍),它们会按照原来的方向前进一步。否则它们会用这一分钟顺时针转 90 度。 同时,它们不会离开地图。
Farmer John 深知牛的移动方法,他也这么移动。
每次(每分钟)Farmer John 和两头牛的移动是同时的。如果他们在移动的时候穿过对方,但是没有在同一格相遇,我们不认为他们相遇了。当他们在某分钟末在某格子相遇,那么追捕结束。
读入十行表示地图。每行都只包含 10 个字符,表示的含义和上面所说的相同。保证地图中只有一个 F 和一个 C。F 和 C 一开始不会处于同一个格子中。
计算 Farmer John 需要多少分钟来抓住他的牛,假设牛和 Farmer John 一开始的行动方向都是正北(即上)。 如果 John 和牛永远不会相遇,输出 0。
思路都在下面,我和其他题解有一个不一样的地方是,我判断不可能抓到的条件是cnt已经过了10000分钟,这个不会超时,并且如果10X10的格子抓一万次才抓到这个数据也够恶心的了
#include<bits/stdc++.h>
using namespace std;
char m[15][15];
int main(){
int dx,dy,nx,ny;
for(int i=1;i<=10;i++){ //将整个布局记录进去,并且把F和C的坐标记录下来
for(int j=1;j<=10;j++){
cin>>m[i][j];
if(m[i][j]=='F'){
dx=i;dy=j; //
}else if(m[i][j]=='C'){
nx=i;ny=j; //
}
}
}
//cout<<dx<<" "<<dy<<" "<<nx<<" "<<ny<<endl; //检查用的 看看坐标有没有错误
int cnt=0,idx[4]={-1,0,1,0},idy[4]={0,1,0,-1},d=0,n=0;
bool sht=true;
int flag=0,flag1=0; //为F和C各立一个flag,如果他们转了4次以上方向就证明是个死胡同,直接输出0即可
while(sht){
if(flag==4||cnt>10000){ //如果flag改变了五次,或者cnt走了一万次就证明是死胡同,直接输出0即可
cout<<0;
return 0;
}
if(dx==nx&&dy==ny){ //如果F和C的坐标相等,直接输出cnt记录的数量即可
cout<<cnt;
return 0;
}
if(m[dx+idx[d]][dy+idy[d]]=='.'){ //核心代码
m[dx][dy]='.'; //每次先判断一下当前方向的下一个坐标是不是. 如果是的话
dx+=idx[d]; //将当前坐标赋值为. 然后将坐标移到下一个位置
dy+=idy[d];
flag=0; //如果能走得通,就把flag重置
}else //如果走不动 就d++改变一下方向并且flag要++;
{
d++;
d=d%4;
flag++;}
if(m[nx+idx[n]][ny+idy[n]]=='.'){ //C的思路也是一样,改一下坐标即可
m[nx][ny]='.';
nx+=idx[n];
ny+=idy[n];
flag1=0;
}else
{
n++;
n=n%4;
flag1++;}
cnt++; //不管是移动了还是试图换了方向,都要加1分钟
// cout<<dx<<" "<<dy<<" "<<nx<<" "<<ny<<" "<<d<<endl; 调试用,方便看看他们每次的坐标
}
cout<<cnt;
return 0;
}