两只牛逃跑到了森林里。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
和一个 C
。F
和 C
一开始不会处于同一个格子中。
计算 Farmer John 需要多少分钟来抓住他的牛,假设牛和 Farmer John 一开始的行动方向都是正北(即上)。 如果 John 和牛永远不会相遇,输出 0。
输入共十行,每行 10 个字符,表示如上文描述的地图。
输出一个数字,表示 John 需要多少时间才能抓住牛们。如果 John 无法抓住牛,则输出 0。
*...*.....
......*...
...*...*..
..........
...*.F....
*.....*...
...*......
..C......*
...*.*....
.*.*......
49
翻译来自NOCOW
USACO 2.4
输入一张字符地图,有空地和障碍物以及边界,一个人追一头牛,
人和牛的运动规律相同:碰壁转向,不碰壁则按照现有方向前进一。
如果人可以追上牛则打印花费的时间,反之则输出0.
值得注意的是:人和牛的初始位置也要计入可运动的点。
函数调用时,如果需要改变实参的值,需要在形参前加引用符号&。
计算人和牛运动的最大时间,作为人和牛能不能相遇的循环终止条件:
最大时间应该不超过:牛和人最多有10 * 10 * 4的平方种状态。
定义一个结构体表示人或者牛,四个参数:
name代表是人还是牛,towards代表当前朝向:1代表向北,2 代表东,3代表南,4代表西,初始均为1(题目要求初始是一路向北),x,y代表在二维数组中的位置。
定义一个移动函数:记录牛和人的坐标变化 ,
注意第二个参数必须要加引用符号&,将每轮的数据带出来。
形参有两个:数组和结构体。
大体思路是先判断人物朝向,再判断下一步是否碰壁,如果不碰壁则移动位置,反之则调转方向。
主函数:
定义二维数组存储地图,定义牛和人的结构体,定义花费的时间,
键入地图,记录牛和人的初始坐标给结构体,
值得注意的是:需要将牛和人将初始位置赋值为空地。
计算花费时间:
循环阶数的条件是,是否大于最大时间,先判断牛和人的坐标是否重合,重合则跳出循环,不重合则继续移动,牛和人分别调用移动函数,判断结束后时间加一。
最后,判断人是否遇到了牛,打印相应的结果即可。
#include
using namespace std;
//最大时间应该不超过:牛和人最多有10*10*4的平方种状态
#define MAX_TIME 10000
//定义一个结构体 name代表是人还是牛
typedef struct data {
char name;
//代表当前朝向:1代表向北,2 代表东,3代表南,4代表西,初始均为1
int towards = 1;
//代表当前坐标
int x, y;
} cows;
//移动函数:记录牛和人的坐标变化 ,注意第二个参数必须要加引用符号&,将每轮的数据带出来
void move(char arr[10][10], cows &c) {
//判断移动方向
if (c.towards == 1) {
//向北
//判断是否碰壁
if (arr[c.x - 1][c.y] == '.' && c.x - 1 >= 0) {
//移动
c.x -= 1;
} else {
//碰壁则转向
c.towards = 2;
}
} else if (c.towards == 2) {
//向东
//判断是否碰壁
if (arr[c.x][c.y + 1] == '.' && c.y + 1 < 10) {
//移动
c.y += 1;
} else {
//碰壁则转向
c.towards = 3;
}
} else if (c.towards == 3) {
//向南
//判断是否碰壁
if (arr[c.x + 1][c.y] == '.' && c.x + 1 < 10) {
//移动
c.x += 1;
} else {
//碰壁则转向
c.towards = 4;
}
} else {
//向西
//判断是否碰壁
if (arr[c.x][c.y - 1] == '.' && c.y - 1 >= 0) {
//移动
c.y -= 1;
} else {
//碰壁则转向
c.towards = 1;
}
}
}
int main() {
//定义二维数组存储地图
char arr[10][10];
//定义牛和人
cows f, c;
f.name = 'F';
c.name = 'C';
//定义花费的时间
int times = 0;
//键入地图
for (int i = 0; i < 10; ++i) {
for (int j = 0; j < 10; ++j) {
cin >> arr[i][j];
//记录牛和人的初始坐标,注意:并将初始位置赋值为空地
if (arr[i][j] == f.name) {
f.x = i;
f.y = j;
arr[i][j] = '.';
}
if (arr[i][j] == c.name) {
c.x = i;
c.y = j;
arr[i][j] = '.';
}
}
}
//计算花费时间
while (times < MAX_TIME) {
//判断f,m是否重合
if (f.x == c.x && f.y == c.y) {
//重合即跳出循环
break;
} else {
//不重合则继续移动
//牛的移动
move(arr, c);
//人的移动
move(arr, f);
}
times++;
}
//判断是否抓到了牛
if (times == MAX_TIME) {
//未抓到
cout << 0;
} else {
//抓到了,打印花费的时间
cout << times;
}
return 0;
}