zoukankan      html  css  js  c++  java
  • POJ 2312

    坦克大战,童年回忆

    这道题比较特殊的在于砖墙的出力,很明白的就可以想到距离变为2,然而这样在使用BFS寻求最短路径的时候违背了一个原则,算法导论上有这部分详细介绍,就是关于每时每刻队列内是一个单调不减的数列,此外,头和尾插值最大为1,一次推入一个距离为2的,会破坏BFS这些性质,所以想了一个这种的方法,即,不局限于二维,每次遇到砖块,先“跳到”高一维度,距离仅增加一,而同时在高一维度,只能跳回二维世界,这样强制增加一个额外经过的点,便可以解决这个问题

    #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= 305;
    
    char mz[maxw][maxw];
    int vis[maxw][maxw], dis[maxw][maxw], bw[maxw][maxw];
    int step[4][2]= {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    int si, sj;
    
    int BFS(int m, int n)
    {
    	memset(vis, 0, sizeof(vis));
    	memset(bw, 0, sizeof(bw));
    	vis[si][sj]= 1;
    	dis[si][sj]= 0;
    	queue<pair<int, int> > Q;
    	Q.push(make_pair(si, sj));
    	int x, y, nx, ny;
    	int v;
    
    	while (!Q.empty()){
    		x= Q.front().first;
    		y= Q.front().second;
    		Q.pop();
    		v= dis[x][y]+1;
    		if (bw[x][y]){
    			dis[x][y]= v;
    			bw[x][y]= 0;
    			Q.push(make_pair(x, y));
    			continue;
    		}
    
    		for (int i= 0; i< 4; ++i){
    			nx= x+step[i][0];
    			ny= y+step[i][1];
    			if ('T'== mz[nx][ny]){
    				return v;
    			}
    			if (nx> 0 && nx<= m && ny> 0 && ny<= n && !vis[nx][ny]){
    				if ('E'== mz[nx][ny]){
    					vis[nx][ny]= 1;
    					dis[nx][ny]= v;
    					Q.push(make_pair(nx, ny));
    				}
    				else if ('B'== mz[nx][ny]){
    					bw[nx][ny]= 1;
    					vis[nx][ny]= 1;
    					dis[nx][ny]= v;
    					Q.push(make_pair(nx, ny));
    				}
    			}
    		}
    	}
    
    	return -1;
    }
    
    int main()
    {
    	int m, n;
    	while (~scanf("%d %d", &m, &n) && m){
    		for (int i= 1; i<= m; ++i){
    			scanf("%s", mz[i]+1);
    			for (int j= 1; j<= n; ++j){
    				if ('Y'== mz[i][j]){
    					si= i;
    					sj= j;
    				}
    			}
    		}
    		printf("%d
    ", BFS(m, n));
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    常见WINDOWS运行命令
    CSDN Blog 之七宗罪
    常见进程大全
    开始→运行→输入的命令集锦(网上搜来的)
    20200527:SpringCloud用了那些组件?分布式追踪链怎么做的?熔断器工作原理?
    20200520:分库分表后如何迁移?
    20200523:如何实现并发限流
    20200521:es底层读写原理?倒排索引原理?
    20200525:MQ应用场景、Kafka和rabbit区别?kafka为什么支撑高并发? 来自
    20200519:催收核心业务是什么?
  • 原文地址:https://www.cnblogs.com/Idi0t-N3/p/14668750.html
Copyright © 2011-2022 走看看