• hdu 4634 Swipe Bo 搜索


    典型的bfs模拟 (广度优先搜索) ,不过有好多细节要注意,比如图中如果是  R#  走到这个R的话就无限往右走了,这样就挂了~肯定到不了出口。还有一种容易造成死循环的,比如

    #E##

    DLLL

    D. .U

    D.SU

    RRRU

    这样的话就必须要标记下当前位置某个方向获得钥匙的状态是否被访问过了,获得钥匙的状态可以状态压缩来表示。

    墙角如果遇到转弯了是不会加step的!


    #include <stdio.h>
    #include <string.h>
    #include <queue>
    using namespace std;
    
    struct Point {
    	int x, y, step, dir, now;
    	Point() {}
    	Point(int x, int y, int step, int dir, int now) : x(x), y(y), step(step), dir(dir), now(now) {}
    }cur;
    
    queue<Point> q;
    bool vis[4][1<<7][202][202];
    int n, m, key, id[202][202], mp[333];
    int dx[] = {1, -1, 0, 0};
    int dy[] = {0, 0, 1, -1};
    char s[202][202];
    int full ;
    
    int bfs() {
    	full = (1<<key)-1;
    	while(!q.empty()) {
    		cur = q.front();
    		q.pop();
    		int x = cur.x, y = cur.y, dir = cur.dir, step = cur.step, now = cur.now;
    		int xx = x + dx[dir], yy = y + dy[dir];
    		if(xx < 1 || yy < 1 || xx > n || yy > m)	continue;
    // 模拟走的路程,细节要注意
    		while(s[xx][yy] != '#') {
    			x = xx; y = yy;
    			if(s[xx][yy] == 'K') {
    				now |= id[xx][yy];
    			}
    			if(s[xx][yy] == 'E') {
    				if(now == full)	 return step;
    			}
    			if(mp[s[xx][yy]] >= 0) {
    				dir = mp[s[xx][yy]];
    				if(vis[dir][now][xx][yy])   break;
    				vis[dir][now][xx][yy] = 1;
    			}
    			xx += dx[dir]; yy += dy[dir];
    			if(xx < 1 || yy < 1 || xx > n || yy > m)	break;
    		}
    		if(xx < 1 || yy < 1 || xx > n || yy > m)	continue;
    		if(s[xx][yy] == '#' && mp[s[x][y]] == -1) {
    			for(int i = 0;i < 4; i++) if(i != dir) {
                    if(vis[i][now][x][y]) continue;
                    vis[i][now][x][y] = 1;
    				xx = x+dx[i];yy = y + dy[i];
    				if(s[xx][yy] == '#')	continue;
    				cur = Point(x, y, step+1, i, now);
    				q.push(cur);
    			}
    		}
    	}
    	return -1;
    }
    
    int main(){
    	memset(mp, -1, sizeof(mp));
    	mp['D'] = 0; mp['U'] = 1; mp['R'] = 2 ; mp['L'] = 3;
    	int i, j, x, y, k, l;
    	while(scanf("%d%d", &n, &m) != -1) {
    		for(i = 1;i <= n; i++)
    			scanf("%s", s[i]+1);
            key = 0;
    		for(i = 1;i <= n; i++) {
    			for(j = 1;j <= m; j++)
    				if(s[i][j] == 'K')	{
    					id[i][j] = 1<<key;
    					key++;
    				}
    				else if(s[i][j] == 'S')
    					x = i, y = j;
    		}
            memset(vis ,0, sizeof(vis));
    		while(!q.empty())	q.pop();
    		for(i = 0;i < 4; i++) {
    			cur = Point(x, y, 1, i, 0);
                vis[i][0][x][y] = 1;
    			q.push(cur);
    		}
    		printf("%d
    ", bfs());
    	}
    	return 0;
    }


  • 相关阅读:
    图像膨胀
    图像腐蚀
    C#多线程与异步
    matplotlib画图总结--多子图布局
    matplotlib画图总结--常用功能
    STM32 MCU一次计算优化和提速
    数字麦克风PDM信号采集与STM32 I2S接口应用--笔记目录
    数字麦克风PDM信号采集与STM32 I2S接口应用(三)
    数字麦克风PDM转PCM与STM32 I2S接口应用----重要文档列表
    数字麦克风PDM信号采集与STM32 I2S接口应用(二)
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3233600.html
Copyright © 2020-2023  润新知