首页 > 其他 > 详细

abbott的复仇

时间:2021-02-07 00:05:02      阅读:35      评论:0      收藏:0      [点我收藏+]

技术分享图片

 

#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<queue>
using namespace std;

struct Node//每一个结点的属性
{
    int r,c,dir;
    Node(int a = 0,int b = 0 ,int c = 0):r(a),c(b),dir(c){}
};
int has_eage[100][100][4][3];//记录每个结点以该朝向进来后可以如何转向
Node p[100][100][4];
int d[100][100][4];//用于记录到达该条路线的最短长度,也是防止重复走该路的方法

int r1, c1, dir;//起始位置和朝向
int r2, c2;//终止位置和朝向

const char* dirs = "NESW";//分别代表上右下左
const char* turns = "FLR";//分别代表进入一个结点时该如何走

int dr[] = { -1,0,1,0 };
int dc[] = { 0,1,0,-1 };//根据朝向和转弯方式来移动行列s

int T(char s)
{
    if (s == F)return 0;
    else if (s == L) return 1;
    else if (s == R) return 2;
}
int D(char s)
{
    if (s == N) return 0;
    else if (s == E) return 1;
    else if (s == S) return 2;
    else if (s == W) return 3;
}

Node walk(Node u,int turn)//修改结点的位置与方向
{
    if (turn == 1)u.dir = (u.dir + 3) % 4;
    if (turn == 2)u.dir = (u.dir + 1) % 4;
    return Node(u.r + dr[u.dir], u.c + dc[u.dir], u.dir);
}
void print_ans(Node s)//打印最后结果
{
    vector<Node> v;
    while (true)
    {
        v.push_back(s);
        if (d[s.r][s.c][s.dir] == 0) break;
        s = p[s.r][s.c][s.dir];
    }
    v.push_back(Node(r1, c1, dir));
    int cnt = 0;
    for (int i = v.size() - 1; i >= 0; i--)
    {
        if (cnt % 10 == 0) printf(" ");
        printf(" (%d,%d)", v[i].r, v[i].c);

        if ((++cnt)% 10 ==0) puts("");
    }
    if (v.size() % 10 != 0)printf("\n");
}

void bfs()
{
    queue<Node> q;
    Node u(r1, c1, dir);
    q.push(u);
    memset(d, -1, sizeof(d));
    int h = 0;
    while (!q.empty())
    {
        Node u = q.front(); q.pop();
        if(h)
            if (u.r == r2 && u.c == c2) { print_ans(u); return; }
        if(h++)
            for (int i = 0; i < 3; i++)
            {
                Node v = walk(u,i);
                if (has_eage[u.r][u.c][u.dir][i]&&d[v.r][v.c][v.dir]<0)
                {
                    d[v.r][v.c][v.dir] = d[u.r][u.c][u.dir] + 1;
                    p[v.r][v.c][v.dir] = u;
                    q.push(v);
                }
            }
        else
        {
            Node v = walk(u, 0);
            d[v.r][v.c][v.dir] = d[u.r][u.c][u.dir] + 1;
            p[v.r][v.c][v.dir] = u;
            q.push(v);
        }
    }
    printf(" ");
    printf(" No Solution Possible\n");
}
int main(void)
{
    //int has_eage[100][100][4][3];//记录每个结点以该朝向进来后可以如何转向
    //Node p[100][100][4];
    //int d[100][100][4];
    string m;
    while (cin >> m && m != "END")
    {
        memset(has_eage, 0, sizeof(has_eage));
        memset(p, 0, sizeof(p));
        cout << m << endl;
        int a = 1, b = 1;
        char s;
        cin >> r1 >> c1 >> s >> r2 >> c2;
        dir = D(s);
        has_eage[r1][c1][dir][0] = 1;
        while (cin >> a && a)
        {
            cin >> b;
            string s;
            //将has_eage中结点的转向记录
            while (cin >> s && s != "*")
            {
                for (int i = 0; i < 4; i++)
                {
                    if (*(dirs + i) == s[0])
                    {
                        for (int j = 1; j < s.size(); j++)
                        {
                            int t = T(s[j]);
                            has_eage[a][b][i][t] = 1;
                        }
                        break;
                    }
                }
            }
        }
        bfs();
    }
    return 0;
}

 

abbott的复仇

原文:https://www.cnblogs.com/loliconsk/p/14382516.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!