0.预处理:在边界设置’*’,这样避免了出界
1.关于移动:形参分别表示x,y,方向,标识符(0表示奶牛,1表示农夫),还有一点就是关于转向:经过事实证明:你只有设顺指针转动的顺序对应0123才可以,对这一点我试验了很多次,也还没想通…欢迎大家思考交流qwq
2.如何判断进入死循环?这个问题让我想了很久,最后本蒟蒻不得已看了眼题解qaq,顿时知道了还有专属值这样一个神奇的东西,大意:当奶牛和农夫在任意两个时刻走过了同一个地方,那么就表示进入循环(不难理解),大家在设置专属值数组时,主要看被乘以的那个数字上限,这决定了你开多大的数组,当然了,一般来说,数组越大越好,不然开小了,偶尔会出现一些难以察觉的bug,很让人头疼
下面是大家最爱的代码时间:
#include<bits/stdc++.h>
using namespace std;
int f[3],c[3]; //分别存储坐标,f[0],f[1],f[2],分别表示x坐标,y坐标
//方向0向北,1向东,2向南,3向西.只有这种顺序才可以满足
int ans=0; //分钟数
char map_[12][12];
bool judge[160005];
void move(int x,int y,int towards,int h) //x表示为行,y表示为列,h==0表示奶牛,h==1表示农夫
{
if (towards==0){
if (map_[x-1][y]=='*')
if (h==0) c[2]=1;
else f[2]=1;
else if (h==0) c[0]--;
else if (h==1) f[0]--;
}
else if (towards==1)
{
if (map_[x][y+1]=='*')
if (h==0) c[2]=2;
else f[2]=2;
else if (h==0) c[1]++;
else if (h==1) f[1]++;
}
else if (towards==2)
{
if (map_[x+1][y]=='*')
if (h==0) c[2]=3;
else f[2]=3;
else if (h==0) c[0]++;
else if (h==1) f[0]++;
}
else if(towards==3)
{
if (map_[x][y-1]=='*')
if (h==0) c[2]=0;
else f[2]=0;
else if (h==0) c[1]--;
else if (h==1) f[1]--; //反思:最终的这个c[1]--...f[1]...
} //太容易搞错了
}
int main()
{
for(int i=0;i<=11;++i) map_[i][0]='*',map_[i][11]='*'; //设置边界
for(int i=0;i<=11;++i) map_[0][i]='*',map_[11][i]='*';
for(int i=1;i<=10;++i)
{
for(int j=1;j<=10;++j)
{
cin>>map_[i][j];
if(map_[i][j]=='C') c[0]=i,c[1]=j;
else if(map_[i][j]=='F') f[0]=i,f[1]=j;
}
}
int tdz; //特征值
while(c[0]!=f[0]||c[1]!=f[1])
{
tdz=f[0]+f[1]*10+c[0]*100+c[1]*1000+f[2]*10000+c[2]*40000; //这个参考了题解,反正系数不要一样,相互呈现递增关系.
if(judge[tdz]
{ //经过了相同的地方,如果是,就是说明进入了死循环
cout<<0;
return 0;
}
judge[tdz]=1; //每走一步就保存
move(f[0],f[1],f[2],1); //1判断是农场主,毕竟是农场组先走的(题干说的)
move(c[0],c[1],c[2],0); //最后的0判断是奶牛
++ans;
}
cout<<ans;
return 0;
}