洛谷刷题7:抓牛(P1518)

题目描述

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

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

一个格子可以是:

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

这里有一个地图的例子:

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

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

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

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

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

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

输入格式

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

输出格式

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

输入输出样例

输入 #1
*...*.....
......*...
...*...*..
..........
...*.F....
*.....*...
...*......
..C......*
...*.*....
.*.*......
输出 #1
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种取值,这样算出的,是一个特征值,每一步的特征值都是不一样的,而如果出现一样的情况,说明出现死循环了,农夫永远抓不到牛。



posted @ 2021-02-01 11:52  _翩若惊鸿  阅读(176)  评论(0编辑  收藏  举报