poj 1729 Jack and Jill (搜索,bfs)
原题网址:http://bailian.openjudge.cn/practice/1729
思路:
方法1: 用点对表示两个人的状态,放在队列中(队列也可以用优先队列),当到达一个点对的路径上的最近距离大于先前求得的最近距离则进行更新。
注意:可能两人的最近距离是0,在更新的时候要注意。
方法2: achievalbe(d2) 表示两人在最小距离平方>= d2的情况下是否能够到学校. 用距离的平方刚好能够用二分来确定两人能够到学校的路线的最远的距离.见代码三.
详细代码:
普通队列:
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <algorithm> 5 #include <cmath> 6 #include <stack> 7 using namespace std; 8 9 class PointPair{ 10 public: 11 int r[2],c[2]; 12 PointPair(int r1=0, int c1=0, int r2=0, int c2=0){ 13 r[0]=r1, r[1]=r2; 14 c[0]=c1, c[1]=c2; 15 } 16 }home,tp; 17 int dis(int r1, int c1, int r2, int c2){ 18 return (r1-r2)*(r1-r2)+(c1-c2)*(c1-c2); 19 } 20 int dis(PointPair &a){ 21 return dis(a.r[0], a.c[0], a.r[1], a.c[1]); 22 } 23 24 queue<PointPair> que; 25 int n, dp[30][30][30][30][3], dx[5]={-1,1,0,0,0},dy[5]={0,0,-1,1,0}, 26 hr[2],hc[2],sr[2],sc[2]; 27 char mp[40][40],dir[10]="NSWE";// 28 29 void solve(){ 30 printf("%.2f\n", sqrt(dp[sr[0]][sc[0]][sr[1]][sc[1]][0])); 31 int d1 = dp[sr[0]][sc[0]][sr[1]][sc[1]][1], d2 = dp[sr[0]][sc[0]][sr[1]][sc[1]][2], r1 = sr[0], c1=sc[0], r2=sr[1], c2=sc[1]; 32 stack<int> stk[2]; 33 while(d1!=-1 && d2 !=-1){ 34 stk[0].push(d1), stk[1].push(d2); 35 r1 -= dx[d1], c1 -= dy[d1], 36 r2 -= dx[d2], c2 -= dy[d2]; 37 d1 = dp[r1][c1][r2][c2][1], d2 = dp[r1][c1][r2][c2][2]; 38 } 39 for(int i=0; i<2; ++i){ 40 while(!stk[i].empty() && stk[i].top()!=4){ 41 printf("%c", dir[stk[i].top()]); 42 stk[i].pop(); 43 } 44 printf("\n"); 45 } 46 printf("\n"); 47 } 48 49 int main(){ 50 while(scanf("%d", &n), n){ 51 memset(dp, -1, sizeof(dp)); 52 for(int i=0; i<n; ++i){ 53 scanf("%s", mp[i]); 54 for(int j=0; j<n; ++j){ 55 if(mp[i][j]=='H') 56 hr[0]=i, hc[0]=j; 57 else if(mp[i][j]=='h') 58 hr[1]=i, hc[1]=j; 59 else if(mp[i][j]=='S') 60 sr[0]=i, sc[0]=j; 61 else if(mp[i][j]=='s') 62 sr[1]=i,sc[1]=j; 63 } 64 } 65 home = PointPair(hr[0], hc[0], hr[1], hc[1]); 66 dp[hr[0]][hc[0]][hr[1]][hc[1]][0] = dis(home); 67 que.push(home); 68 while(!que.empty()){ 69 tp = que.front(); que.pop(); 70 for(int i=0; i<4; ++i){ 71 for(int j=0; j<4; ++j){ 72 int r1 = tp.r[0]+dx[i], c1 = tp.c[0]+dy[i], 73 r2 = tp.r[1]+dx[j], c2 = tp.c[1]+dy[j], 74 d1 = i, d2 = j; 75 if(r1<0 || c1<0 || r1==n || c1==n || 76 r2<0 || c2<0 || r2==n || c2==n || 77 mp[r1][c1]=='*' || mp[r2][c2]=='*' || 78 mp[r1][c1]=='s' || mp[r1][c1]=='h'|| 79 mp[r2][c2]=='S' || mp[r2][c2]=='H') 80 continue; 81 // 两人全在school的状态不会出现在队列中 82 if(mp[tp.r[0]][tp.c[0]]=='S') 83 r1=tp.r[0], c1=tp.c[0], d1=4; 84 else if(mp[tp.r[1]][tp.c[1]]=='s') 85 r2=tp.r[1], c2=tp.c[1], d2=4; 86 int d = min(dis(r1,c1,r2,c2), dp[tp.r[0]][tp.c[0]][tp.r[1]][tp.c[1]][0]); 87 if(d <= dp[r1][c1][r2][c2][0]) continue;// 可添加最优性剪枝 88 dp[r1][c1][r2][c2][0] = d; 89 dp[r1][c1][r2][c2][1] = d1; 90 dp[r1][c1][r2][c2][2] = d2; 91 if(mp[r1][c1]=='S' && mp[r2][c2]=='s') continue; 92 que.push(PointPair(r1,c1,r2,c2)); 93 } 94 } 95 } 96 solve(); 97 } 98 return 0; 99 }
优先队列:
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <algorithm> 5 #include <cmath> 6 #include <stack> 7 using namespace std; 8 9 int dis(int r1, int c1, int r2, int c2){ 10 return (r1-r2)*(r1-r2)+(c1-c2)*(c1-c2); 11 } 12 class PointPair{ 13 public: 14 int r[2],c[2]; 15 PointPair(int r1=0, int c1=0, int r2=0, int c2=0){ 16 r[0]=r1, r[1]=r2; 17 c[0]=c1, c[1]=c2; 18 } 19 int operator<(const PointPair &b) const{ 20 return dis(r[0],c[0],r[1],c[1])<dis(b.r[0],b.c[0],b.r[1],b.c[1]); 21 } 22 }home,tp; 23 int dis(PointPair &a){ 24 return dis(a.r[0], a.c[0], a.r[1], a.c[1]); 25 } 26 27 priority_queue<PointPair> que; 28 int n, dp[30][30][30][30][3], dx[5]={-1,1,0,0,0},dy[5]={0,0,-1,1,0}, 29 hr[2],hc[2],sr[2],sc[2], rev[5]={1,0,3,2,4}; 30 char mp[40][40],dir[10]="NSWE";// 31 32 void solve(){ 33 printf("%.2f\n", sqrt(dp[sr[0]][sc[0]][sr[1]][sc[1]][0])); 34 int d1 = dp[sr[0]][sc[0]][sr[1]][sc[1]][1], d2 = dp[sr[0]][sc[0]][sr[1]][sc[1]][2], r1 = sr[0], c1=sc[0], r2=sr[1], c2=sc[1]; 35 stack<int> stk[2]; 36 while(d1!=-1 && d2 !=-1){ 37 stk[0].push(d1), stk[1].push(d2); 38 r1 += dx[rev[d1]], c1 += dy[rev[d1]], 39 r2 += dx[rev[d2]], c2 += dy[rev[d2]]; 40 d1 = dp[r1][c1][r2][c2][1], d2 = dp[r1][c1][r2][c2][2]; 41 } 42 for(int i=0; i<2; ++i){ 43 while(!stk[i].empty() && stk[i].top()!=4){ 44 printf("%c", dir[stk[i].top()]); 45 stk[i].pop(); 46 } 47 printf("\n"); 48 } 49 printf("\n"); 50 } 51 52 int main(){ 53 while(scanf("%d", &n), n){ 54 memset(dp, -1, sizeof(dp)); 55 for(int i=0; i<n; ++i){ 56 scanf("%s", mp[i]); 57 for(int j=0; j<n; ++j){ 58 if(mp[i][j]=='H') 59 hr[0]=i, hc[0]=j; 60 else if(mp[i][j]=='h') 61 hr[1]=i, hc[1]=j; 62 else if(mp[i][j]=='S') 63 sr[0]=i, sc[0]=j; 64 else if(mp[i][j]=='s') 65 sr[1]=i,sc[1]=j; 66 } 67 } 68 home = PointPair(hr[0], hc[0], hr[1], hc[1]); 69 dp[hr[0]][hc[0]][hr[1]][hc[1]][0] = dis(home); 70 que.push(home); 71 while(!que.empty()){ 72 // tp = que.front(); que.pop(); 73 tp = que.top(); que.pop(); 74 for(int i=0; i<4; ++i){ 75 for(int j=0; j<4; ++j){ 76 int r1 = tp.r[0]+dx[i], c1 = tp.c[0]+dy[i], 77 r2 = tp.r[1]+dx[j], c2 = tp.c[1]+dy[j], 78 d1 = i, d2 = j; 79 if(r1<0 || c1<0 || r1==n || c1==n || 80 r2<0 || c2<0 || r2==n || c2==n || 81 mp[r1][c1]=='*' || mp[r2][c2]=='*' || 82 mp[r1][c1]=='s' || mp[r1][c1]=='h'|| 83 mp[r2][c2]=='S' || mp[r2][c2]=='H') 84 continue; 85 // 两人全在school的状态不会出现在队列中 86 if(mp[tp.r[0]][tp.c[0]]=='S') 87 r1=tp.r[0], c1=tp.c[0], d1=4; 88 else if(mp[tp.r[1]][tp.c[1]]=='s') 89 r2=tp.r[1], c2=tp.c[1], d2=4; 90 int d = min(dis(r1,c1,r2,c2), dp[tp.r[0]][tp.c[0]][tp.r[1]][tp.c[1]][0]); 91 if(d <= dp[r1][c1][r2][c2][0]) continue;// 可添加最优性剪枝 92 dp[r1][c1][r2][c2][0] = d; 93 dp[r1][c1][r2][c2][1] = d1; 94 dp[r1][c1][r2][c2][2] = d2; 95 if(mp[r1][c1]=='S' && mp[r2][c2]=='s') continue; 96 que.push(PointPair(r1,c1,r2,c2)); 97 } 98 } 99 } 100 solve(); 101 } 102 return 0; 103 }
View Code
方法二:
1 #include <cstdio> 2 #include <cmath> 3 #include <queue> 4 #include <stack> 5 #include <cstring> 6 #include <algorithm> 7 8 using namespace std; 9 10 char mp[40][40], dir[] = "NSWE", rdir[] = "SNEW"; 11 int n, dp[30][30][30][30], mk[30][30][30][30]; 12 int dy[4] = {0, 0, -1, 1}, dx[4] = {-1, 1, 0, 0}; 13 14 class Point{ 15 public: 16 int x, y; 17 Point(int _x=0, int _y=0): x(_x), y(_y) {} 18 }home[2], sch[2]; 19 20 21 int dis2(Point a, Point b){ 22 return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y); 23 } 24 25 26 bool not_in_map(int x){ 27 return x < 0 || x >= n; 28 } 29 30 31 int achievable(int d, int print=0){ 32 queue<int> que; 33 34 memset(dp, 0x8, sizeof(dp)); 35 36 if(min(dis2(home[0], home[1]), dis2(sch[0], sch[1])) < d) 37 return 0; 38 dp[home[0].x][home[0].y][home[1].x][home[1].y] = 0; 39 que.push(home[0].x); que.push(home[0].y); que.push(home[1].x); que.push(home[1].y); 40 41 while(!que.empty()){ 42 int x0, y0, x1, y1; 43 x0 = que.front(); que.pop(); y0 = que.front(); que.pop(); 44 x1 = que.front(); que.pop(); y1 = que.front(); que.pop(); 45 for(int i=0; i<4; ++i){ 46 for(int j=0; j<4; ++j){ 47 int tx0 = x0, ty0 = y0, tx1 = x1, ty1 = y1; 48 if(!(x0 == sch[0].x && y0 == sch[0].y)) 49 tx0 += dx[i], ty0 += dy[i]; 50 if(!(x1 == sch[1].x && y1 == sch[1].y)) 51 tx1 += dx[j], ty1 += dy[j]; 52 if(not_in_map(tx0) || not_in_map(ty0) || not_in_map(tx1) || not_in_map(ty1)) 53 continue; 54 if(mp[tx0][ty0] == '*' || mp[tx0][ty0] == 'S' || mp[tx0][ty0] == 'H') 55 continue; 56 if(mp[tx1][ty1] == '*' || mp[tx1][ty1] == 's' || mp[tx1][ty1] == 'h') 57 continue; 58 if(dis2(Point(tx0, ty0), Point(tx1, ty1)) < d) 59 continue; 60 if(dp[tx0][ty0][tx1][ty1] > dp[x0][y0][x1][y1] + 1){ 61 dp[tx0][ty0][tx1][ty1] = dp[x0][y0][x1][y1] + 1; 62 que.push(tx0); que.push(ty0); que.push(tx1); que.push(ty1); 63 if(mp[tx0][ty0] == 's' && mp[tx1][ty1] == 'S') 64 return 1; 65 } 66 } 67 } 68 } 69 70 return 0; 71 } 72 73 74 void print_path(){ 75 stack<char> p[2]; 76 int x0 = sch[0].x, y0 = sch[0].y, x1 = sch[1].x, y1 = sch[1].y; 77 78 while(!(mp[x0][y0] == 'h' && mp[x1][y1] == 'H')){ 79 for(int i=0; i<5; ++i){ 80 for(int j=0; j<5; ++j){ 81 int tx0 = x0, ty0 = y0, tx1 = x1, ty1 = y1; 82 if(i < 4 || mp[x0][y0] != 's') 83 tx0 += dx[i], ty0 += dy[i]; 84 if(j < 4 || mp[x1][y1] != 'S') 85 tx1 += dx[j], ty1 += dy[j]; 86 if(i == 4 && j == 4) 87 continue; 88 if(not_in_map(tx0) || not_in_map(ty0) || not_in_map(tx1) || not_in_map(ty1)) 89 continue; 90 if(!(dp[tx0][ty0][tx1][ty1] + 1 == dp[x0][y0][x1][y1])) 91 continue; 92 if(mp[tx0][ty0] != 's') 93 p[0].push(rdir[i]); 94 if(mp[tx1][ty1] != 'S') 95 p[1].push(rdir[j]); 96 if(mp[tx0][ty0] == 'h' && mp[tx1][ty1] == 'H'){ 97 for(int k=0; k<2; ++k){ 98 while(!p[1-k].empty()){ 99 printf("%c", p[1-k].top()); p[1-k].pop(); 100 } 101 printf("\n"); 102 } 103 return; 104 } 105 x0 = tx0, y0 = ty0, x1 = tx1, y1 = ty1; 106 goto out; 107 } 108 } 109 out: {} 110 } 111 } 112 113 114 int main(){ 115 freopen("input.txt", "r", stdin); 116 117 while(scanf("%d", &n) && n){ 118 for(int i=0; i<n; ++i){ 119 scanf("%s", mp[i]); 120 for(int j=0; j<n; ++j){ 121 switch(mp[i][j]){ 122 case 'h': home[0] = Point(i, j); break; 123 case 'H': home[1] = Point(i, j); break; 124 case 's': sch[0] = Point(i, j); break; 125 case 'S': sch[1] = Point(i, j); break; 126 default: break; 127 } 128 } 129 } 130 131 int mx = min(dis2(home[0], home[1]), dis2(sch[0], sch[1])) + 1, mn = 0; 132 while(mx > mn){ 133 int d = (mx + mn) >> 1; 134 if(achievable(d)) 135 mn = d + 1; 136 else 137 mx = d; 138 } 139 achievable(mx - 1); 140 printf("%.2f\n", sqrt(mx - 1)); 141 print_path(); 142 } 143 144 return 0; 145 }
View Code
转载于:https://www.cnblogs.com/yyf2016/p/5789382.html
poj 1729 Jack and Jill (搜索,bfs)相关推荐
- poj 1729 Jack and Jill 1376 Robot 1324 Holedox Moving 1475 Pushing Boxes bfs + a*
poj 1729 Jack and Jill Jack和Jill要从各自的家走到各自的学校,但是他们俩各自不喜欢对方,因此,需要你找到两个人行走的路线,使得他们路线中两个人最近的直线距离最长.单位时间 ...
- 广度优先搜索(BFS)——抓住那头牛(POJ 4001)
本文将以(POJ 4001)抓住那头牛 为例,讲解经典算法广度优先搜索(BFS)的STL写法 在实际写算法中,怎么能不使用更快.更方便.更准确.更高效的C++ STL模板呢 相信很多人都了解过广度优先 ...
- 广度优先搜索 BFS算法
广度优先搜索算法(Breadth-First-Search,BFS),又称作宽度优先搜索.BFS算法是从根节点开始,沿着树的宽度遍历树的节点.如果所有节点均被访问,则算法中止. 算法思想 1.首先将根 ...
- 一文搞定深度优先搜索(DFS)与广度优先搜索(BFS)【含完整源码】
写在前面:博主是一位普普通通的19届双非软工在读生,平时最大的爱好就是听听歌,逛逛B站.博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事 ...
- POJ 1321-棋盘问题-简单搜索DFS
POJ 1321-棋盘问题-简单搜索DFS Description 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编 ...
- 【算法】深度搜索(DFS) 和 广度搜索(BFS)
深度搜索(DFS) 点:然后退回到该顶点,搜索其它路径,直到以该顶点为始点的所有路径的顶点都被访问,深度搜索算法是递归算法,因为对于没一个节点来说,执行的是同样的操作. 简单来说,深度搜素算法就是一 ...
- 广度/宽度优先搜索(BFS)详解
1.前言 广度优先搜索(也称宽度优先搜索,缩写BFS,以下采用广度来描述)是连通图的一种遍历策略.因为它的思想是从一个顶点V0开始,辐射状地优先遍历其周围较广的区域,故得名. 一般可以用它做什么呢?一 ...
- 人工智能课后作业_python实现广度优先遍历搜索(BFS)(附源码)
2 广度优先遍历搜索(BFS) 2.1算法介绍 2.2实验代码 2.3实验结果 2.4实验总结 2.1算法介绍 广度优先搜索算法(英语:Breadth-First-Search,缩写为BFS),是一种 ...
- 【蓝桥杯】历届试题 青蛙跳杯子(广度优先搜索bfs)(C++)
[蓝桥杯]历届试题 青蛙跳杯子 问题描述 思路分析 代码实现 问题描述 题目链接:青蛙跳杯子 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 X星球的流行宠物是青蛙,一般有两种颜色: ...
最新文章
- 拆解多轴步进电机控制器
- IDA中的SIG应用
- 关于jsp web项目,jsp页面与servlet数据不同步的解决办法(报错404、405等)即访问.jsp和访问web.xml中注册的/servlet/的区别
- JVM插桩之二:Java agent基础原理
- [如何做研究][如何写论文]
- 【Kafka】Kafka Schema Registry 原理
- 上海工程技术大学c语言试卷,上海工程技术大学2009-2010C语言试卷A.doc
- 羽毛球 vs. 软件开发
- 32、[源码]-AOP原理-创建AOP代理
- java提高篇(十九)-----数组之二
- 使用casewhen来判断执行不同的sql
- 互联网人必备的六大类专业搜索工具
- python电影评价分析_Python浅谈分析某电影数据
- 恭贺德林教点穴网成立
- 聊聊小程序第三方登录
- 如何维持手机电池寿命_教你如何让自己的手机电池寿命多用两年
- krpano 如何开启调试
- jit和jitx区别_JIT模式
- datagrid全选
- Qt数据可视化(QBoxPlotSeries盒须图)
热门文章
- Android使用NDK OpenGL ES3.0绘制一个三角形
- Pandas库(2):数据的统计分析
- HihoCoder - 1175 拓扑排序·二
- SQL Server 2008 R2的发布订阅配置实践
- Redis学习笔记之入门基础知识——简介
- Linux0.11内核--加载可执行二进制文件之1.copy_strings
- TabActivity 切换到后台遇到的问题
- 链接器工具错误 LNK2019 必须在友元声明中显式指定模板参数
- POJ2631 Roads in the North
- python实现定时发送qq消息