用三维数组保存运动物体第一次处于x、y坐标和某方向时所用步数,同时记录当运动物体的路径和出现循环时的周期。这一步用BFS完成。
枚举两个运动物体路径中的公共位置,根据情况分类讨论。
有3种情况。
1,人和牛都处于循环路径中。即判断A+xa=B+y+b,用拓展欧几里德求解。
2,人和牛都不在循环路径中。即判断A=B。
3,人和牛只有一个在循环路径中。即判断A+xa=B。
/*
ID: kkkwjx1
PROG: ttwo
LANG: C++
*/
#include <iostream>
#include <cstdio>
#include <map>
#include <vector>
#include <string>
#include <stack>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=15;
char grid[maxn][maxn];
struct Character
{
int x,y;
int dir,step;
int period;
int vis[maxn][maxn][4];
vector<pair<int,pair<int,int> > > path;
Character():dir(0),step(0)
{
memset(vis,-1,sizeof(vis));
}
};
Character farmer,cow;
const int mv[4][2]= {-1,0,0,1,1,0,0,-1};
bool judge(int x,int y)
{
return 0<=x&&x<10&&0<=y&&y<10&&grid[x][y]!='*';
}
void bfs(Character &actor)
{
while(true)
{
if(actor.vis[actor.x][actor.y][actor.dir]!=-1)
{
actor.period=actor.step-actor.vis[actor.x][actor.y][actor.dir];
return ;
}
actor.path.push_back(make_pair(actor.dir,make_pair(actor.x,actor.y)));
actor.vis[actor.x][actor.y][actor.dir]=actor.step;
int nx=actor.x+mv[actor.dir][0],ny=actor.y+mv[actor.dir][1];
if(!judge(nx,ny))
actor.dir=(actor.dir+1)%4;
else
{
actor.x=nx;
actor.y=ny;
}
++actor.step;
}
}
int e_gcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int ans=e_gcd(b,a%b,x,y);
int temp=x;
x=y;
y=temp-a/b*y;
return ans;
}
int meet()
{
int ans=0;
for(int i=0; i<farmer.path.size(); ++i)
{
for(int j=0; j<cow.path.size(); ++j)
{
if(farmer.path[i].second!=cow.path[j].second)
continue;
int a=0,b=0;
if(farmer.path.size()-farmer.period<=i)
a=farmer.period;
if(cow.path.size()-cow.period<=j)
b=cow.period;
int res=-1;
int A=farmer.vis[farmer.path[i].second.first][farmer.path[i].second.second][farmer.path[i].first];
int B=cow.vis[cow.path[j].second.first][cow.path[j].second.second][cow.path[j].first];
if(a&&b)
{
int x,y;
int d=e_gcd(a,b,x,y);
int c=-A+B;
if(c%d!=0)
continue;
d=c/d;
x=abs(x*d);
y=abs(y*d);
res=min(A,B)+max(x*a,y*b);
}
else if(a==0&&b==0)
{
if(A==B)
res=A;
}
else
{
if(a==0)
{
swap(a,b);
swap(A,B);
}
int Z=B-A;
if(Z>=0&&Z%a==0)
res=B;
}
if(res!=-1)
{
if(ans==0||res<ans)
ans=res;
}
}
}
return ans;
}
int main()
{
freopen("ttwo.in","r",stdin);
freopen("ttwo.out","w",stdout);
for(int i=0; i<10; ++i)
{
scanf("%s",grid[i]);
for(int j=0; grid[i][j]; ++j)
{
if(grid[i][j]=='F')
{
farmer.x=i;
farmer.y=j;
}
else if(grid[i][j]=='C')
{
cow.x=i;
cow.y=j;
}
}
}
bfs(farmer);
bfs(cow);
int ans=meet();
printf("%d\n",ans);
return 0;
}