zoukankan      html  css  js  c++  java
  • POJ 3083

    一道非常有意思的题

    小时候看书看到过这种迷宫走法

    整道题可以分为两个部分讨论:

    • BFS部分,很简单,而且由于图的设置,使得这道题没什么难度
    • 模拟这种迷宫走法的部分,开始很不好想关于这种转向的走法,后面取巧这么设置(以左墙寻路为例): 首先,决定下一步的step变量,按着索引递增,四个方向设置成逆时针(顺也可,就是一个符号处理的问题,只要满足一直即可),寻路过程中记录一个to(toward)记录当前寻路朝向,每当在一个新的地方寻路的时候,首先将这个方向逆时针掰过来,再顺时针遍历四个可以找的方向,中间如果找到路,就跳出来

    中间DEBUG时候遇到过死循环,是关于模运算中负数的处理,所以干脆将这个模运算利用位运算解决

    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <stack>
    #include <map>
    #include <set>
    using namespace std;
    
    const int maxw= 45;
    const int LEFT= -1;
    const int RIGHT= 1;
    
    struct Node
    {
    	int i, j;
    	Node(int _i= 0, int _j= 0) : i(_i), j(_j) {}
    };
    int w, h;
    char mz[maxw][maxw];
    bool vis[maxw][maxw];
    int dis[maxw][maxw];
    int step[4][2]= {{1, 0}, {0, -1}, {-1, 0}, {0, 1}};
    
    int BFS(int si, int sj)
    {
    	queue<Node> Q;
    	memset(vis, 0, sizeof(vis));
    	vis[si][sj]= 1;
    	dis[si][sj]= 1;
    	Q.push(Node(si, sj));
    	Node cur;
    	int i, j, v;
    
    	while (!Q.empty()){
    		cur= Q.front();
    		Q.pop();
    		i= cur.i;
    		j= cur.j;
    		v= dis[i][j]+1;
    
    		for (int p= 0; p< 4; ++p){
    			int ni= i+step[p][0], nj= j+step[p][1];
    			if ('E'== mz[ni][nj]){
    				return v;
    			}
    			if ('.'== mz[ni][nj] && !vis[ni][nj]){
    				vis[ni][nj]= 1;
    				dis[ni][nj]= v;
    				Q.push(Node(ni, nj));
    			}
    		}
    	}
    
    	return -1;
    }
    int Search(const int si, const int sj, const int dir)
    {
    	int ni, nj;
    	int to= -1;
    	for (int i= 0; i< 4; ++i){
    		ni= si+step[i][0];
    		nj= sj+step[i][1];
    		if ('.'== mz[ni][nj]){
    			to= i;
    			break;
    		}
    	}
    	dis[si][sj]= 1;
    	dis[ni][nj]= 2;
    	int v;
    
    	while ('E'!= mz[ni][nj]){
    		v= dis[ni][nj]+1;
    		to= (to+dir*1)&3;
    		for (int i= 0; i< 4; ++i){
    			int x= ni+step[to][0], y= nj+step[to][1];
    			if ('E'== mz[x][y]){
    				return v;
    			}
    			if ('.'== mz[x][y]){
    				dis[x][y]= v;
    				ni= x;
    				nj= y;
    				break;
    			}
    			to= (to-dir*1)&3;
    		}
    	}
    
    	return -1;
    }
    
    int main()
    {
    	int kase;
    	scanf("%d", &kase);
    
    	while (kase--){
    		scanf("%d %d", &w, &h);
    		memset(mz, '#', sizeof(mz));
    		int si, sj;
    		for (int i= 1; i<= h; ++i){
    			scanf(" %s", mz[i]+1);
    			for (int j= 1; j<= w; ++j){
    				if ('S'== mz[i][j]){
    					si= i;
    					sj= j;
    					break;
    				}
    			}
    		}
    
    		int ans_l, ans_r, ans_s;
    		ans_l= Search(si, sj, LEFT);
    		ans_r= Search(si, sj, RIGHT);
    		ans_s= BFS(si, sj);
    		printf("%d %d %d
    ", ans_l, ans_r, ans_s);
    	}
    	return 0;
    }
    
  • 相关阅读:
    (1)李宏毅深度学习-----机器学习简介
    Git命令之不得不知的git stash暂存命令
    Http2升级方案调研
    神奇的 SQL 之别样的写法 → 行行比较
    熔断机制
    限流算法
    状态机
    布隆过滤器
    负载均衡算法
    K8S Ingress
  • 原文地址:https://www.cnblogs.com/Idi0t-N3/p/14688653.html
Copyright © 2011-2022 走看看