P1518 [USACO2.4] 两只塔姆沃斯牛 The Tamworth Two

[USACO2.4] 两只塔姆沃斯牛 The Tamworth Two

题目描述

两只牛逃跑到了森林里。Farmer John 开始用他的专家技术追捕这两头牛。你的任务是模拟他们的行为(牛和 John)。

追击在 10 × 10 10 \times 10 10×10 的平面网格内进行。一个格子可以是:一个障碍物,两头牛(它们总在一起),或者 Farmer John。两头牛和 Farmer John 可以在同一个格子内(当他们相遇时),但是他们都不能进入有障碍的格子。

一个格子可以是:

  • . 空地;
  • * 障碍物;
  • C 两头牛;
  • F Farmer John。

这里有一个地图的例子:

*...*.....
......*...
...*...*..
..........
...*.F....
*.....*...
...*......
..C......*
...*.*....
.*.*......

牛在地图里以固定的方式游荡。每分钟,它们可以向前移动或是转弯。如果前方无障碍(地图边沿也是障碍),它们会按照原来的方向前进一步。否则它们会用这一分钟顺时针转 90 度。 同时,它们不会离开地图。

Farmer John 深知牛的移动方法,他也这么移动。

每次(每分钟)Farmer John 和两头牛的移动是同时的。如果他们在移动的时候穿过对方,但是没有在同一格相遇,我们不认为他们相遇了。当他们在某分钟末在某格子相遇,那么追捕结束。

读入十行表示地图。每行都只包含 10 个字符,表示的含义和上面所说的相同。保证地图中只有一个 F 和一个 CFC 一开始不会处于同一个格子中。

计算 Farmer John 需要多少分钟来抓住他的牛,假设牛和 Farmer John 一开始的行动方向都是正北(即上)。 如果 John 和牛永远不会相遇,输出 0。

输入格式

输入共十行,每行 10 个字符,表示如上文描述的地图。

输出格式

输出一个数字,表示 John 需要多少时间才能抓住牛们。如果 John 无法抓住牛,则输出 0。

样例 #1

样例输入 #1

*...*.....
......*...
...*...*..
..........
...*.F....
*.....*...
...*......
..C......*
...*.*....
.*.*......

样例输出 #1

49

解题思路

  1. 读取输入地图: 首先,你需要读取输入的地图,将每个格子的信息存储到一个二维数组中,用于后续的模拟。
  2. 初始化位置和方向: 定义农夫 John(F)和两只牛(C)的初始位置和行动方向。你可以使用变量来记录它们的行、列坐标和方向。
  3. 模拟移动: 使用循环来模拟每一分钟的移动。在每一分钟内,分别对农夫 John 和两只牛执行以下步骤:
  4. 如果当前方向上的下一个格子是空地,将位置前进一步。
  5. 如果当前方向上的下一个格子是障碍物或边界,将方向顺时针旋转 90 度。
  6. 注意:方向的变化要通过 % 4 来确保循环在 0-3 之间。
  7. 判断相遇和行动次数: 在每一分钟内的模拟中,检查农夫 John
    和两只牛的位置是否相同。如果相遇,输出当前的行动次数,并结束程序。如果超过了一定次数的行动(比如500次),输出0,并结束程序。
  8. 输出结果: 如果循环结束时农夫 John 和两只牛仍未相遇,则输出0,表示无法相遇。

#include 

using namespace std;

int main() {
    char map[10][10];
    int Fi, Fj, Ft = 0, Ci, Cj, Ct = 0;
    for (int i = 0; i < 10; ++i) {
        for (int j = 0; j < 10; ++j) {
            cin >> map[i][j];//输入地图
            if (map[i][j] == 'F') {//保存F的位置
                Fi = i;
                Fj = j;
            }
            if (map[i][j] == 'C') {//保存C的位置
                Ci = i;
                Cj = j;
            }
        }
    }
    int count = 0;
    while (true) {
        //F的行动
        if (Ft == 0 && Fi - 1 >= 0 && map[Fi - 1][Fj] != '*') { Fi--; }//F朝北,且没到边界,且不为阻碍,前进
        else if (Ft == 0 && (Fi - 1 < 0 || map[Fi - 1][Fj] == '*')) { Ft = (Ft + 1) % 4; }//F朝北,到了边界,或遇到阻碍,原位置顺时针转90度
        else if (Ft == 1 && Fj + 1 <= 9 && map[Fi][Fj + 1] != '*') { Fj++; }//F朝东,且没到边界,且不为阻碍,前进
        else if (Ft == 1 && (Fj + 1 > 9 || map[Fi][Fj + 1] == '*')) { Ft = (Ft + 1) % 4; }//F朝东,到了边界,或遇到阻碍,原位置顺时针转90度
        else if (Ft == 2 && Fi + 1 <= 9 && map[Fi + 1][Fj] != '*') { Fi++; }//F朝南,且没到边界,且不为阻碍,前进
        else if (Ft == 2 && (Fi + 1 > 9 || map[Fi + 1][Fj] == '*')) { Ft = (Ft + 1) % 4; }//F朝南,到了边界,或遇到阻碍,原位置顺时针转90度
        else if (Ft == 3 && Fj - 1 >= 0 && map[Fi][Fj - 1] != '*') { Fj--; }//F朝西,且没到边界,且不为阻碍,前进
        else if (Ft == 3 && (Fj - 1 < 0 || map[Fi][Fj - 1] == '*')) { Ft = (Ft + 1) % 4; }//F朝西,到了边界,或遇到阻碍,原位置顺时针转90度
        //C的行动
        if (Ct == 0 && Ci - 1 >= 0 && map[Ci - 1][Cj] != '*') { Ci--; }//C朝北,且没到边界,且不为阻碍,前进
        else if (Ct == 0 && (Ci - 1 < 0 || map[Ci - 1][Cj] == '*')) { Ct = (Ct + 1) % 4; }//C朝北,到了边界,或遇到阻碍,原位置顺时针转90度
        else if (Ct == 1 && Cj + 1 <= 9 && map[Ci][Cj + 1] != '*') { Cj++; }//C朝东,且没到边界,且不为阻碍,前进
        else if (Ct == 1 && (Cj + 1 > 9 || map[Ci][Cj + 1] == '*')) { Ct = (Ct + 1) % 4; }//C朝东,到了边界,或遇到阻碍,原位置顺时针转90度
        else if (Ct == 2 && Ci + 1 <= 9 && map[Ci + 1][Cj] != '*') { Ci++; }//C朝南,且没到边界,且不为阻碍,前进
        else if (Ct == 2 && (Ci + 1 > 9 || map[Ci + 1][Cj] == '*')) { Ct = (Ct + 1) % 4; }//C朝南,到了边界,或遇到阻碍,原位置顺时针转90度
        else if (Ct == 3 && Cj - 1 >= 0 && map[Ci][Cj - 1] != '*') { Cj--; }//C朝西,且没到边界,且不为阻碍,前进
        else if (Ct == 3 && (Cj - 1 < 0 || map[Ci][Cj - 1] == '*')) { Ct = (Ct + 1) % 4; }//C朝西,到了边界,或遇到阻碍,原位置顺时针转90度
        count++;
        if (Fi == Ci && Fj == Cj) {
            cout << count;
            return 0;
        } else if (count > 500) {
            cout << 0;
            return 0;
        }
    }
}

你可能感兴趣的:(洛谷普及,算法)