USACO-The Tamworth Two
来源:http://ace.delos.com/usacoprob2?a=F5gG3hMiHdO&S=ttwo
这题是简单的模拟题,当然你也可以用数学的方法做,我个人推崇KISS原则。
这题的唯一亮点就是无解的判断,我敲代码也懒得想,因为递归到43000左右就爆栈了,所以我到40000时就掐断,这是我的战果:
现在,给出判断无解的方法:
1.无解则无论牛还是农夫,他们的路线都是有周期的,考虑:在某一点上,怎么知道他们一定在走之前走过的路?因为每个点都只有四个方向,如果一个点走超过四次,则它肯定在走之前走过的路,当然,你也可以用数组存储每个点都走过什么方向,那么下次走到此点时直接判断方向就行了,不用判断次数。
2.牛和农夫的周期一般是不同的,那么就要判断他们所在位置是否都同时在走之前走过的路。如果同时满足,则肯定无解,如果一个在走之前走过的路,一个在走新路,则不能判断是否无解。
3.上面的方法已经足够判断无解了,这里再给出一种方法:因为每个点最多走不超过四次,则如果走的次数比(10*10*4)=400次,则基本上可以判断无解了。亲测AC了。
4.由于这个无解的判断条件比较宽松,所以基本上怎么做都可以= =
/* ID:ay27272 PROG:ttwo LANG:C++ */ #include <iostream> #include <cstdio> #include <stdlib.h> #include <cstring> using namespace std; const int XX[]={-1,0,1,0}; //顺时针,0为上 const int YY[]={0,1,0,-1}; bool map[15][15]; void dfs(int cx,int cy,int cc,int fx,int fy,int ff,int time) //一大堆变量看得烦心了 { if (time>400) { cout<<0<<endl; exit(0); } if (cx==fx && cy==fy) { cout<<time<<endl; exit(0); } cx+=XX[cc]; cy+=YY[cc]; if (cx>=0 && cx<10 && cy>=0 && cy<10 && map[cx][cy]){} else {cx-=XX[cc]; cy-=YY[cc]; cc=(cc+1)%4;} fx+=XX[ff]; fy+=YY[ff]; if (fx>=0 && fx<10 && fy>=0 && fy<10 && map[fx][fy]){} else {fx-=XX[ff]; fy-=YY[ff]; ff=(ff+1)%4;} dfs(cx,cy,cc,fx,fy,ff,time+1); } int main() { freopen("ttwo.in","r",stdin); freopen("ttwo.out","w",stdout); int cx,cy,fx,fy; memset(map,false,sizeof(map)); char ch; for (int i=0;i<10;i++) for (int j=0;j<10;j++) { scanf("%c",&ch); while (ch=='\n') scanf("%c",&ch); if (ch=='.') map[i][j]=true; else if (ch=='*') map[i][j]=false; else if (ch=='F') {fx=i; fy=j; map[i][j]=true;} //原来的位置也是能走的 else if (ch=='C') {cx=i; cy=j; map[i][j]=true;} } dfs(cx,cy,0,fx,fy,0,0); return 0; }