USACOThe 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;
}
原文地址:https://www.cnblogs.com/ay27/p/2780164.html