HDU 4634 Swipe Bo

来源:互联网 发布:淘宝去边框代码 编辑:程序博客网 时间:2024/05/18 11:48

题目链接:Swipe Bo

解题思路:这个题目刚开始搞不清楚是为什么要判断两次方向,只能按照kuangbin大爷的写了。。。。。


根据代码来说第一个转向就是对于当前即将要扩展的节点进行一次方向判定,如果这个点不是转向标志的话,这里不起作用。

根据代码来说第二个转向就是对于下一节点进行判断,如果这里其作用的话,那么下一个循环的初始还会进行判断,那么这里就像当余无用了。


但是有一种情况就是,我当前节点是转向节点,走到了下一个节点又是一个转向节点,如果不对这个节点判断的话,就有可能出现不按照该方向节点指示的方向来走。方向就会错误。主要是影响触碰#的那一下。

##

RE

US

##

这种情况下,答案就会+1,然后成为WA自动机。

#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#define MAX 220#define MAXN 130using namespace std;struct node{    int x, y, k, s;    node(){}    node(int xx, int yy, int kk, int ss){        x = xx, y = yy, k = kk, s = ss;    }};char g[MAX][MAX];bool v1[MAX][MAX][MAXN][4];bool v[MAX][MAX][MAXN];int n, m, ans;int kx[10], ky[10], ktot;int sx, sy;int dir[4][2] = {1,0,-1,0,0,1,0,-1};void init(){    ans = -1;    ktot = 0;}int getKey(int x, int y){    for(int i = 0; i < ktot; i++){        if(kx[i] == x && ky[i] == y){            return i;        }    }    return -1;}int getDir(char c){    if(c == 'D') return 0;    if(c == 'U') return 1;    if(c == 'R') return 2;    if(c == 'L') return 3;    return -1;}bool check(int x, int y){    if(x < 0 || x >= n || y < 0 || y >= m){        return false;    }    return true;}void bfs(){    int i, j, k;    queue<node> mq;    memset(v, false, sizeof(v));    memset(v1, false, sizeof(v1));    mq.push(node(sx, sy, 0, 0));    v[sx][sy][0] = true;    while(!mq.empty()){        node s = mq.front();        //printf("%d %d %d %d\n", s.x, s.y, s.s, s.k);        mq.pop();        for(i = 0; i < 4; i++){            int xx = s.x;            int yy = s.y;            int kk = s.k;            int hh = i;            while(1){                //printf("$%d %d %d %d\n",i, xx, yy, hh);                if(getDir(g[xx][yy]) != -1){                    hh = getDir(g[xx][yy]);                }                if(v1[xx][yy][kk][hh]) break;                v1[xx][yy][kk][hh] = true;                xx += dir[hh][0];                yy += dir[hh][1];                if(!check(xx, yy))break;                if(g[xx][yy] == '#')break;                //printf("#%d %d %d %d\n", i, xx, yy, hh);                if(g[xx][yy] == 'E' && kk == (1 << ktot) - 1){                    ans = s.s + 1;                    return;                }                if(getDir(g[xx][yy]) != -1){                    hh = getDir(g[xx][yy]);                    //printf("dir = %d %c\n", hh, g[xx][yy]);                }                if(g[xx][yy] == 'K'){                    kk |= (1 << getKey(xx, yy));                }                if(check(xx + dir[hh][0], yy + dir[hh][1]) && g[xx + dir[hh][0]][yy + dir[hh][1]] == '#'){                    //printf("in = %d %d %d %d\n", xx, yy, kk, hh);                    if(v[xx][yy][kk])break;                    mq.push(node(xx, yy, kk, s.s + 1));                    v[xx][yy][kk] = true;                    break;                }            }        }    }}int main(){    int i, j, k;    #ifndef ONLINE_JUDGE    //freopen("1.in", "r", stdin);    #endif // ONLINE_JUDGE    while(~scanf("%d%d", &n, &m)){        init();        for(i = 0; i < n; i++){            getchar();            for(j = 0; j < m; j++){                g[i][j] = getchar();                if(g[i][j] == 'K'){                    kx[ktot] = i;                    ky[ktot++] = j;                }                if(g[i][j] == 'S'){                    sx = i, sy = j;                }            }        }       // printf("%d %d\n", sx, sy);        bfs();        printf("%d\n", ans);    }    return 0;}


0 0