• UVa 816


    题意

    最多有9*9个节点的迷宫, 这个迷宫特殊的是, 每个节点可走的方向是特定的. 比如 1 2 WLF * 这个指令的意思是若朝向西来到点(1,2), 可以选择左转或直走
    uva816

    思路

    BFS
    一开始用数组做的模拟, 上交RE了, 不知道原因是什么
    学习紫书写法, 利用队列和结构体

    AC代码

    #include <iostream>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    
    using namespace std;
    
    char name[25], str[10];
    int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
    
    //借助 strchr() 函数可以查找字符串s中首次出现字符c的位置这一功能将下列字母标序号
    const char* ds = "NESW";  //标号为0-3 北东南西
    const char* ts = "FLR";  //标号为0-2 直左右
    int ds_id( char c ){ return strchr(ds, c) - ds; }
    int ts_id( char c ){ return strchr(ts, c) - ts; }
    int x1, y1, x2, y2, t;
    char tt;
    
    struct Node{
        int x, y, a;
        Node(int x = 0, int y = 0, int a = 0):x(x),y(y),a(a){}
    };
    
    bool judge[10][10][5][5], pla[10][10];
    int vis[10][10][5];
    Node pre[10][10][5];
    void PRINT( Node u ){
        vector<Node> n;
        for(;;){
            n.push_back(u);
            if( vis[u.x][u.y][u.a] == 0 )   break;
            u = pre[u.x][u.y][u.a];
        }
        n.push_back(Node(x1,y1,t));
        int cnt = 0;
        for( int i = n.size()-1; i >= 0; i-- ){
            cnt++;
            if( cnt % 10 == 1 )     printf(" ");
            printf(" (%d,%d)",n[i].x, n[i].y);
            if( cnt % 10 == 0 || i == 0 )   putchar('
    ');
        }
    }
    Node getv( Node u, int i ){  //i=0:直走,方向不变,  i=1:左转,  i=2:右转
        int a = u.a;
        if( i == 1 )   a = u.a-1 < 0 ? 3 : u.a-1;
        else if( i == 2 )   a = u.a+1 > 3 ? 0 : u.a+1;
        return Node(u.x+dir[a][0], u.y+dir[a][1], a );
    }
    
    void bfs()
    {
        queue<Node> q;
        Node u(x1 + dir[t][0], y1 + dir[t][1], t);
        vis[u.x][u.y][u.a] = 0;
        q.push(u);
        while( !q.empty() ){
            Node u = q.front();
            q.pop();
            if( u.x == x2 && u.y == y2 ){
                PRINT(u);
                return;
            }
            for( int i = 0; i < 3; i++ ){
                Node v = getv(u, i);
                if( judge[u.x][u.y][u.a][i] && vis[v.x][v.y][v.a] < 0 && pla[v.x][v.y] ){
                    vis[v.x][v.y][v.a] = vis[u.x][u.y][u.a] + 1;
                    pre[v.x][v.y][v.a] = u;
                    q.push(v);
                }
            }
        }
        printf("  No Solution Possible
    ");
        return;
    }
    
    void readin()
    {
        scanf("%d%d %c %d%d",&x1, &y1, &tt, &x2, &y2);
        pla[x1][y1] = true;
        pla[x2][y2] = true;
        t = ds_id(tt);
        int aa, bb;
        while( scanf("%d",&aa) && aa){
            scanf("%d",&bb);
            pla[aa][bb] = true;
            while( scanf("%s",str) && strcmp(str, "*") != 0 ){
                int len = strlen(str);
                for( int i = 1; i < len; i++ )
                    judge[aa][bb][ds_id(str[0])][ts_id(str[i])] = true;
            }
        }
    }
    
    void solve()
    {
        memset(judge, 0, sizeof(judge));
        memset(vis, -1, sizeof(vis));
        memset(pla, 0, sizeof(pla));
        readin();
        printf("%s
    ",name);
        bfs();
    }
    
    int main()
    {
        while( ~scanf("%s",name) && strcmp(name, "END") != 0 )
            solve();
        return 0;
    }

    RE代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    
    const int maxn = 10000;
    char name[25], str[10];
    int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
    int pre[maxn];
    //借助 strchr() 函数可以查找字符串s中首次出现字符c的位置这一功能将下列字母标序号
    const char* ds = "NESW";  //标号为0-3 北东南西
    const char* ts = "FLR";  //标号为0-2 直左右
    int ds_id( char c ){ return strchr(ds, c) - ds; }
    int ts_id( char c ){ return strchr(ts, c) - ts; }
    int x1, y1, x2, y2, t;
    char tt;
    bool flag;
    
    struct Node{ int x, y, a; };
    Node p[maxn];
    bool judge[10][10][5][5], vis[10][10][5], pla[10][10];
    
    int cnt = 0;
    void PRINT( int a ){
        int t = pre[a];
        if( t != 0 )
            PRINT(t);
        else{
            printf(" (%d,%d)",x1, y1);
            printf(" (%d,%d)",p[0].x, p[0].y);
            cnt += 2;
        }
        printf(" (%d,%d)",p[a].x, p[a].y);
        cnt += 1;
        if( cnt % 10 == 0 ) putchar('
    ');
    }
    
    void bfs()
    {
        int head = 0, tail = 1, m, n, o, mm, nn, oo;
        p[0].x = x1 + dir[t][0], p[0].y = y1 + dir[t][1], p[0].a = t;
        pre[0] = -1;
        while( head < tail ){
            m = p[head].x, n = p[head].y, o = p[head].a;
            //cout << m << ' ' << n << ' ' << o << endl;
            if( m == x2 && n == y2 ){
                PRINT(head);
                flag = true;
                return;
            }
            for( int i = 0; i < 3; i++ ){
                if( judge[m][n][o][i] ){  //i=0:直走,方向不变,  i=1:左转,  i=2:右转
                    if( i == 0 )    oo = o;
                    else if( i == 1 )   oo = o-1 < 0 ? 3 : o-1;
                    else if( i == 2 )   oo = o+1 > 3 ? 0 : o+1;
                    mm = m + dir[oo][0];
                    nn = n + dir[oo][1];
                }
                if( !vis[mm][nn][oo] && pla[mm][nn] ){
                    //cout << mm << ' ' << nn << ' ' << endl;
                    vis[mm][nn][oo] = true;
                    p[tail].x = mm;
                    p[tail].y = nn;
                    p[tail].a = oo;
                    pre[tail] = head;
                    tail++;
                }
            }
            head++;
        }
        return;
    }
    
    void readin()
    {
        scanf("%d%d %c %d%d",&x1, &y1, &tt, &x2, &y2);
        pla[x1][y1] = true;
        pla[x2][y2] = true;
        t = ds_id(tt);
        int aa, bb;
        while( scanf("%d",&aa) && aa){
            scanf("%d",&bb);
            pla[aa][bb] = true;
            while( scanf("%s",str) && strcmp(str, "*") != 0 ){
                int len = strlen(str);
                for( int i = 1; i < len; i++ )
                    judge[aa][bb][ds_id(str[0])][ts_id(str[i])] = true;
            }
        }
    }
    
    void solve()
    {
        memset(judge, 0, sizeof(judge));
        memset(vis, 0, sizeof(vis));
        memset(pla, 0, sizeof(pla));
        flag = false;
        readin();
        printf("%s
    ",name);
        bfs();
        if( !flag ) printf(" No Solution Possible");
        putchar('
    ');
    }
    
    int main()
    {
        while( ~scanf("%s",name) && strcmp(name, "END") != 0 )
            solve();
        return 0;
    }
  • 相关阅读:
    linux下的crontab定时执行任务命令详解
    494. Target Sum
    347. Top K Frequent Elements
    5. Longest Palindromic Substring
    时间复杂度计算方法
    62. Unique Paths
    54. Spiral Matrix && 59. Spiral Matrix II
    57. Insert Interval
    53. Maximum Subarray
    42.Trapping rain water
  • 原文地址:https://www.cnblogs.com/JinxiSui/p/9740596.html
Copyright © 2020-2023  润新知