洛谷刷题7:抓牛(P1518)
题目描述
两只牛逃跑到了森林里。Farmer John 开始用他的专家技术追捕这两头牛。你的任务是模拟他们的行为(牛和 John)。
追击在 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
这道题还是有学到很多东西的
从设计移动函数,判断是否抓到,到如何判断出现重复情况
具体见代码:
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<math.h>
#include<string>
#include<cstdio>
using namespace std;
char map[12][12];//地图
int fx, fy, cx, cy;//农夫和牛的坐标
int direction_f = 0, direction_c = 0;//农夫和牛的方向
int coordinatemove[4][2] = { {-1,0},{0,1},{1,0},{0,-1} };
bool judge[160005];
int seconds = 0;
bool verdict()//判断是否抓住了
{
if (fx == cx && fy == cy)return 0;
else return 1;
}
void move()
{
if (map[fx + coordinatemove[direction_f][0]][fy + coordinatemove[direction_f][1]] == '*')
direction_f = (direction_f + 1) % 4;
else
fx += coordinatemove[direction_f][0], fy += coordinatemove[direction_f][1];
if(map[cx + coordinatemove[direction_c][0]][cy + coordinatemove[direction_c][1]] == '*')
direction_c = (direction_c + 1) % 4;
else
cx += coordinatemove[direction_c][0], cy += coordinatemove[direction_c][1];
}
int main()
{
for (int i = 0; i <= 11; i++)
map[0][i] = '*', map[i][0] = '*', map[i][11] = '*', map[11][i] = '*';
for (int i = 1; i <= 10; i++)
for (int j = 1; j <= 10; j++)
{
cin >> map[i][j];
if (map[i][j] == 'F')fx = i, fy = j;
if (map[i][j] == 'C')cx = i, cy = j;
}
while (verdict())
{
int p = fx + fy * 10 + cx * 100 + cy * 1000 + direction_f * 10000 + direction_c * 40000;//建立特征值
seconds++;
move();
if (judge[p])
{
cout << 0;
return 0;
}
judge[p] = 1;
}
cout << seconds;
return 0;
}
这里的特征值值得一提
为什么要fx + fy * 10 + cx * 100 + cy * 1000 + direction_f * 10000 + direction_c * 40000这样算呢?
这是因为,fx,fy,cx.cy各有十种取值,direction_f,direction_c各有4种取值,这样算出的,是一个特征值,每一步的特征值都是不一样的,而如果出现一样的情况,说明出现死循环了,农夫永远抓不到牛。