• HDU3085 Nightmare Ⅱ (双向BFS)


    联赛前该练什么?DP,树型,状压当然是爆搜啦
    双向BFS就是两个普通BFS通过一拼接函数联系,多多判断啦

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #define R(a,b,c) for(register int a = (b); a <= (c); ++a)
    #define nR(a,b,c) for(register int a = (b); a >= (c); --a)
    #define Fill(a,b) memset(a, b, sizeof(a))
    #define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
    
    #define ON_DEBUGG
    
    #ifdef ON_DEBUGG
    
    #define D_e_Line printf("
    -----------
    ")
    #define D_e(x) std::cout << (#x) << " : " <<x << "
    "
    #define FileOpen() freopen("in.txt", "r", stdin)
    #define FileSave() freopen("out.txt", "w", stdout)
    #define Pause() system("pause")
    #include <ctime>
    #define TIME() fprintf(stderr, "
    TIME : %.3lfms
    ", clock() * 1000.0 / CLOCKS_PER_SEC)
    
    #else
    
    #define D_e_Line ;
    #define D_e(x) ;
    #define FileOpen() ;
    #define FilSave ;
    #define Pause() ;
    #define TIME() ;
    
    #endif
    
    struct ios {
    	template<typename ATP> ios& operator >> (ATP &x) {
    		x = 0; int f = 1; char c;
    		for(c = getchar(); c < '0' || c > '9'; c = getchar()) if(c == '-') f = -1;
    		while(c >= '0' && c <= '9') x = x * 10 + (c ^ '0'), c = getchar();
    		x *= f;
    		return *this;
    	}
    }io;
    
    using namespace std;
    
    template<typename ATP> inline ATP Min(ATP a, ATP b) {
    	return a < b ? a : b;
    }
    template<typename ATP> inline ATP Max(ATP a, ATP b) {
    	return a > b ? a : b;
    }
    #include <queue>
    
    const int N = 1007;
    
    int n, m;
    struct Nod {
    	int x, y;
    };
    queue<Nod> q[2];
    int step, mx, my, gx, gy, zx[5], zy[5], vis[2][N][N];
    int dx[] = {0, 0, -1, 1}, dy[] = {1, -1, 0, 0};
    char mp[N][N];
    inline bool Check(int x, int y) {
    	return (abs(x - zx[1]) + abs(y - zy[1]) > 2 * step) && (abs(x - zx[2]) + abs(y - zy[2]) > 2 * step);
    }
    inline bool Valid(int x, int y) {
    	return x >= 1 && x <= n && y >= 1 && y <= m && mp[x][y] != 'X';
    }
    inline bool BFS(int t) { // t = 1 -> man, t = 0 -> woman
    	int siz = q[t].size();
    	while(siz--){
    		int x = q[t].front().x, y = q[t].front().y;
    		q[t].pop();
    		if(!Check(x, y)) continue;
    		R(k,0,3){
    			int fx = x + dx[k], fy = y + dy[k];
    			if(!Valid(fx, fy)) continue;
    			if(vis[t][fx][fy]) continue;
    			if(!Check(fx, fy)) continue;
    			vis[t][fx][fy] = true;
    			if(vis[0][fx][fy] && vis[1][fx][fy]) return true;
    			q[t].push((Nod){ fx, fy});
    		}
    	}
    	return false;
    }
    
    inline int Solve() {
    	q[0].push((Nod){ mx, my});
    	q[1].push((Nod){ gx, gy});
    	step = 0;
    	while(!q[0].empty() || !q[1].empty()){
    		++step;
    		R(i,1,3){
    			if(BFS(0)) return step; // man move three times
    		}
    		if(BFS(1)) return step; // woman move
    	}
    	return -1;
    }
    int main() {
    //FileOpen();
    	int Tasks;
    	io >> Tasks;
    	while(Tasks--){
    		io >> n >> m;
    		R(i,1,n){
    			scanf("%s", mp[i] + 1);
    		}
    		int nmIdx = 0; // night mare
    		while(!q[0].empty()) q[0].pop();
    		while(!q[1].empty()) q[1].pop();
    		Fill(vis, 0);
    		R(i,1,n){
    			R(j,1,m){
    				if(mp[i][j] == 'M'){
    					mx = i, my = j;
    					vis[0][i][j] = true;
    				}
    				else if(mp[i][j] == 'G'){
    					gx = i, gy = j;
    					vis[1][i][j] = true;
    				}
    				else if(mp[i][j] == 'Z'){
    					zx[++nmIdx] = i, zy[nmIdx] = j;
    				}
    			}			
    		}
    		printf("%d
    ", Solve());
    	}
    	return 0;
    }
    
  • 相关阅读:
    使用commonscompress操作zip文件(压缩和解压缩)
    BoneCP的使用
    Struts2多文件上传
    shell 脚本转换 十六进制 十进制 八进制 二进制
    磁盘 I/O 性能监控指标和调优方法
    需求分析的故事——如何练就需求分析的火眼金晴?
    Debian 修改IP地址或DNS
    mysql主从备份
    ThinkPad T400 安装Windows Server 2008详细过程
    debian下,怎么ll命令注册
  • 原文地址:https://www.cnblogs.com/bingoyes/p/11697022.html
Copyright © 2020-2023  润新知