zoukankan      html  css  js  c++  java
  • POJ 1101

    这道题提交的时候都战战兢兢,一道核心思想为BFS的题目也可以出的这么刁钻

    • 这道题一个非常亮点的地方,在于求的是线段数目最短,而不是路径长度最短,最开始一直WA在这里了(一个最短路径也许会很曲折的拐很多弯,而线段数目最短也许走的很远,但实际上线段数目少)

    • 这就给BFS使用出了一个大难题,因为如果还按照常规的一次走一步然后入一个点到队列的想法,就会导致bfs队列中节点一个很重要的性质不能满足,这部分可以详见算法导论(队列中节点的距离值是不减的,并且最小值和最大值差距最大是1之类的性质)

    • 所以,解法是一个方向搜索,一次走到底

    • 此外无脑step 4个方向走一遍固然可以解决问题,可是,仔细想来会出现同一水平(或垂直)方向回来会走的毛病,此处可以进行剪枝,在构造step数组的时候,稍微留了个心眼,使得处在水平方向或是垂直方向的两个反方向数组序列号和为3(详见代码)进行优化,效率显著...

    其实这道题很久之前做过一次,但还是被卡死,还是不够熟练,好在这次更深刻体会了一把

    #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= 80;
    
    char bod[maxw][maxw];
    int step[4][2]= {{1, 0}, {0, 1}, {0, -1}, {-1, 0}};
    int w, h;
    int dis[maxw][maxw], vis[maxw][maxw], fa[maxw][maxw];
    
    int BFS(const int &x1, const int &y1, const int &x2, const int &y2)
    {
    	memset(vis, 0, sizeof(vis));
    	queue<pair<int, int> > Q;
    	vis[y1][x1]= 1;
    	dis[y1][x1]= 0;
    	fa[y1][x1]= -1;
    	Q.push(make_pair(y1, x1));
    	int y, x, ny, nx;
    	int v, flag;
    
    	while (!Q.empty()){
    		pair<int, int> tp= Q.front();
    		Q.pop();
    		y= tp.first;
    		x= tp.second;
    		v= dis[y][x]+1;
    
    		for (int i= 0; i< 4; ++i){
    			if (3== i+fa[y][x] || i== fa[y][x]){
    				continue;
    			}
    			flag= 1;
    			ny= y+step[i][0];
    			nx= x+step[i][1];
    			while (ny>= 0 && ny<= h && nx>= 0 && nx<= w && (flag= ' '== bod[ny][nx])){
    				if (!vis[ny][nx]){
    					vis[ny][nx]= 1;
    					dis[ny][nx]= v;
    					fa[ny][nx]= i;
    					Q.push(make_pair(ny, nx));
    				}
    				ny+= step[i][0];
    				nx+= step[i][1];
    			}
    			if (!flag){
    				if (y2== ny && x2== nx){
    					return v;
    				}
    			}
    		}
    	}
    
    	return -1;
    }
    
    int main()
    {
    	int ks_bd= 0, ks_p;
    	int x1, y1, x2, y2;
    	int ans;
    	while (~scanf("%d %d%*c", &w, &h) && w){
    		ks_p= 0;
    		memset(bod[0], ' ', (w+2)*sizeof(char));
    		memset(bod[h+1], ' ', (w+2)*sizeof(char));
    		++w;
    		for (int i= 1; i<= h; ++i){
    			bod[i][0]= ' ';
    			scanf("%[^
    ]%*c", bod[i]+1);
    			bod[i][w]= ' ';
    		}
    		++h;
    		printf("Board #%d:
    ", ++ks_bd);
    		while (scanf("%d %d %d %d", &x1, &y1, &x2, &y2) && x1){
    			ans= BFS(x1, y1, x2, y2);
    			if (-1== ans){
    				printf("Pair %d: impossible.
    ", ++ks_p);
    			}
    			else{
    				printf("Pair %d: %d segments.
    ", ++ks_p, ans);
    			}
    		}
    		putchar('
    ');
    	}
    	return 0;
    }
    
  • 相关阅读:
    vue-cli3和element做一个简单的登陆页面
    用vue和layui简单写一个响应式数据展示表
    js中的AJAX
    js个人笔记简记
    解决sublime快捷键回车换行问题
    Sublime设置格式化代码快捷键ctrl+shift+r
    2020前端最新面试知识点汇总
    cookie,sessionstorage,localstorage区别
    linux/centos7安装mysql
    linux基本命令的操作
  • 原文地址:https://www.cnblogs.com/Idi0t-N3/p/14664834.html
Copyright © 2011-2022 走看看