Fairy tale(BFS + 大模拟)

一.题目链接:

Fairy tale

二.题目大意:

给你一个N × N 的地图,图上的每个点有四种方向(E W S N),代表着移动方向.

在 t = 0 时,saya 在 (1, 1),treasure 在 (n, n).

在每个单位时间内,分为 3 步.

① saya 先按照地图移动一个单位.

② saya 可以向四个方向移动一个单位,saya 会移动到距离 treasure 最近的位置

     如果四个方向距离都一样,那么 saya 不移动.

     否则,按照 E > W > N > S 移动.

③ treasure 按照地图移动. 

在每个单位时间后,地图会改变.

规则如下:E -> W -> S -> N -> E.

在 x<= 100 步时

如果 saya 能得到 treasure,输出 "Get the treasure! At step x."

如果 saya 陷入循环,输出 "Impossible. At step x."

否则输出 "Not sure."

三.分析:

这题本身不难,主要在于对题意的准确理解 和 细节的处理.

一开始就是因为没理解好题意一直 WA.

比如是 saya 的两步先移动完,treasure 才移动.

还有就是必须是四个方向的距离都相等才不动.

如果有一个方向出界,其他方向都相等,此时还是要按照优先级移动的.

四.代码实现:

#include <set>
#include <map>
#include <ctime>
#include <queue>
#include <cmath>
#include <stack>
#include <vector>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define eps 1e-4
#define PI acos(-1.0)
#define ll long long int
using namespace std;

const int M = 35;
const int inf = 0x3f3f3f3f;
int maze[M][M];
int ans1, ans2;
int dir[4][2] = {{0, 1}, {0, -1}, {-1, 0}, {1, 0}};///E > W > N > S (y, x)
struct node
{
    int y1, x1;///saya
    int y2, x2;///treasure
}s[110];

bool loop(int step)
{
    for(int i = step % 4; i < step; i += 4)
    {
        if(s[step].x1 == s[i].x1 && s[step].y1 == s[i].y1 && s[step].x2 == s[i].x2 && s[step].y2 == s[i].y2)
            return 1;
    }
    return 0;
}

void Move1(int step, int n)
{
    int yy = s[step + 1].y1 = s[step].y1;
    int xx = s[step + 1].x1 = s[step].x1;
    if((maze[yy][xx] + step) % 4 == 0 && xx + 1 <= n)
        s[step + 1].x1 = xx + 1;
    else if((maze[yy][xx] + step) % 4 == 1 && xx - 1 >= 1)
        s[step + 1].x1 = xx - 1;
    else if((maze[yy][xx] + step) % 4 == 2 && yy + 1 <= n)
        s[step + 1].y1 = yy + 1;
    else if((maze[yy][xx] + step) % 4 == 3 && yy - 1 >= 1)
        s[step + 1].y1 = yy - 1;
}

void Move2(int step, int n)
{
    int yy = s[step + 1].y2 = s[step].y2;
    int xx = s[step + 1].x2 = s[step].x2;
    if((maze[yy][xx] + step) % 4 == 0 && xx + 1 <= n)
        s[step + 1].x2 = xx + 1;
    else if((maze[yy][xx] + step) % 4 == 1 && xx - 1 >= 1)
        s[step + 1].x2 = xx - 1;
    else if((maze[yy][xx] + step) % 4 == 2 && yy + 1 <= n)
        s[step + 1].y2 = yy + 1;
    else if((maze[yy][xx] + step) % 4 == 3 && yy - 1 >= 1)
        s[step + 1].y2 = yy - 1;
}

int better(int y1, int x1, int y2, int x2)
{
    int dis1 = (y1 - y2) * (y1 - y2);
    int dis2 = (x1 - x2) * (x1 - x2);
    return dis1 + dis2;
}

void dfs(int step, int n)
{
    if(step > 100)
        return;
    if(s[step].x1 == s[step].x2 && s[step].y1 == s[step].y2)
    {
        ans1 = step;
        return;
    }
    if(loop(step))
    {
        ans2 = step;
        return;
    }
    Move1(step, n);
    Move2(step, n);
    int dis[5];
    int Min = inf;
    for(int i = 0; i < 4; ++i)
    {
        dis[i] = inf;
        int yy = s[step + 1].y1 + dir[i][0];
        int xx = s[step + 1].x1 + dir[i][1];
        if(yy >= 1 && yy <= n && xx >= 1 && xx <= n)
            dis[i] = better(yy, xx, s[step].y2, s[step].x2);
        if(dis[i] < Min)
            Min = dis[i];
    }
    if(dis[0] == dis[1] && dis[0] == dis[2] && dis[0] == dis[3]);
    else if(dis[0] == Min)
        s[step + 1].x1++;
    else if(dis[1] == Min)
        s[step + 1].x1--;
    else if(dis[2] == Min)
        s[step + 1].y1--;
    else if(dis[3] == Min)
        s[step + 1].y1++;
    dfs(step + 1, n);
}

int main()
{
    int n;
    int c = 0;
    while(~scanf("%d", &n) && n)
    {
        for(int i = 1; i <= n; ++i)
        {
            getchar();
            for(int j = 1; j <= n; ++j)
            {
                char ch;
                scanf("%c", &ch);
                switch(ch)
                {
                    case 'E': maze[i][j] = 0;break;
                    case 'W': maze[i][j] = 1;break;
                    case 'S': maze[i][j] = 2;break;
                    case 'N': maze[i][j] = 3;break;
                }
            }
        }
        ans1 = ans2 = -1;
        s[0].x1 = s[0].y1 = 1;
        s[0].x2 = s[0].y2 = n;
        dfs(0, n);
        printf("Case %d:\n", ++c);
        if(ans1 == -1 && ans2 == -1)
            printf("Not sure.\n");
        else if(ans1 != -1)
            printf("Get the treasure! At step %d.\n", ans1);
        else
            printf("Impossible. At step %d.\n", ans2);
        printf("\n");
    }
    return 0;
}

 

全部评论

相关推荐

ddd7_:跟我一模一样,加微信的hr都同一个,扫码了白年书人查看图片
点赞 评论 收藏
分享
程序员花海:实习太简单了 学历可以的 实习描述应该是先介绍业务 再介绍技术 技术咋推动业务的 做到了啥收益 有没有做实验 实验组和对照组有什么不同 你最后学到了什么 有没有参与处理过线上问题 有没有参与过公司的code review 有没有参与过技术分享 这些都是可以在实习描述中写的 并且实习和项目不一样不会撞车 应该放在最前面 放在教育背景下面 另外项目有点烂大街 可以看下我主页的简历优化案例
秋招,不懂就问
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务