FZU - 1019猫捉老鼠

一只猫和一只老鼠在10*10的迷宫中。迷宫中的每个方格可以是空的,或者含有障碍。猫和老鼠可以进入任意一个空的方格中。当他们相遇时,猫和老鼠在同一个方格中。但是,无论猫或老鼠都不能进入有障碍的方格。我们可以用字符组成的二维数组表示迷宫,如下图所示。

老鼠在迷宫中按照一种固定的方式行走:每个时刻,老鼠都向它所面对的方向前进一格,这需要花费1秒时间。如果前方是一个障碍或者是迷宫的边界,它将花1秒的时间按顺时针方向转90度。

为了抓到老鼠,这只猫决定也按照与老鼠相同的行走方式行进。

猫和老鼠在每个单位时间内是同时行动的。因此,如果猫和老鼠在行进过程中“擦肩而过”,猫是无法捉到老鼠的。只有当猫和老鼠同时到达一个相同的格子时,猫才能捉住老鼠。
初始时,猫和老鼠不会在同一个方格中。并且它们都面向北方。
你的任务是编一个程序,求出猫捉到老鼠的所花时间。
Input
输入数据的第一行n,表示输入数据的组数。
每组数据由10行组成,每行10个字符,表示迷宫的地图以及猫和老鼠的初始位置。输入数据保证只有一只猫和一只老鼠。
每组输入数据之后均有一个空行作为间隔。
Output
对于每组给定的输入,输出一行仅含一个数,即猫捉到老鼠所花的时间。如果猫永远都无法抓到老鼠,则输出0。
Sample Input
1
…..
……*…
..
……….
…*.c….
…..
…*……
..m……*
.….
..……
Sample Output
49

题意:

有个迷宫,有一只猫和一只老鼠,他们按同种方式行走,一开始面朝北方,走一格花一秒,如果是障碍或者边界,就顺时针转90度。转方向一次也是一秒,当他们走到一个格子就结束。擦肩而过就是俩人面对面,但是下一秒俩人走到了对方的格子,这一种不算抓住。

思路:

模拟他们的行走的方式,就可以判断了,但是有个问题,如果永远遇不到,怎么判断。有俩种方法,一种是开一个标记数组,如果在某一刻,他们回到过去一个相同的状态,那么他们就进入循环。
一种是,循环到一定次数后直接跳出。你可以假定一万,一万不行,十万。好像有个方法可以算出来。我是第一种。

# include <cstdio>
# include <cstring>
using namespace std;

int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1}; //前进的变量,分别是上,左,下,右,对应于顺时针的顺序

int main()
{
    int T;
    char a[15][15]; // 存储迷宫
    int mark[11][11][11][11][4][4]; //标记数组,分别是猫和鼠的位置和他们面朝的方向
    scanf("%d",&T); 

    while(T--)
    {
        int f = 0;
        memset(mark,0,sizeof(mark));
        int c = 0,m = 0; //面朝的方向 
        int x[2],y[2];
        for(int i = 0;i < 10;i++)
        {
            scanf("%s",a[i]);
        }
        for(int i = 0;i < 10;i++)
        {
            for(int j = 0;j < 10;j++)  //找到猫和鼠的位置
            {
                if(a[i][j] == 'c')
                {
                    x[0] = i,y[0] = j;
                }
                if(a[i][j] == 'm')
                {
                    x[1] = i,y[1] = j;
                }
            }
        }
        int ans = 0;
        while(true) //循环,模拟他们的行进过程
        {
            mark[x[0]][y[0]][x[1]][y[1]][c][m] = 1;  //把当前的状态标记
            if(x[0]+dx[c] >= 0 && x[0]+dx[c] < 10 && y[0]+dy[c] >= 0 && y[0]+dy[c] < 10)
            {  //判断是否超出边界
                if(a[x[0]+dx[c]][y[0]+dy[c]] != '*')  //如果不是障碍,就可以到达
                {
                    x[0] += dx[c];
                    y[0] += dy[c];
                }
                else  //否则就转方向
                    c = (c+1) % 4;
            }
            else  //超出边界转向
            {
                c = (c+1) % 4;
            }

            if(x[1]+dx[m] >= 0 && x[1]+dx[m] < 10 && y[1]+dy[m] >= 0 && y[1]+dy[m] < 10)
            { //老鼠和上面的猫类似
                if(a[x[1]+dx[m]][y[1]+dy[m]] != '*')
                {
                    x[1] += dx[m];
                    y[1] += dy[m];
                }
                else
                    m = (m+1) % 4;
            }
            else
                m = (m+1) % 4;
            if(mark[x[0]][y[0]][x[1]][y[1]][c][m] == 1)  //如果变化后的状态已经出现过,跳出
            {
                f = 1;
                break;
            }
            ans++;
            if(x[0] == x[1] && y[0] == y[1]) //如果猫和老鼠在一个格子,就跳出
                break;
        }
        if(f)
            printf("0\n");
        else
            printf("%d\n",ans);
    }
    return 0;
} 

猜你喜欢

转载自blog.csdn.net/fadedsun/article/details/77484425