码迷,mamicode.com
首页 > 其他好文 > 详细

poj 1729 Jack and Jill (搜索,bfs)

时间:2016-08-20 00:04:37      阅读:208      评论:0      收藏:0      [点我收藏+]

标签:

原题网址:http://bailian.openjudge.cn/practice/1729

思路:

  用点对表示两个人的状态,放在队列中(队列也可以用优先队列),当到达一个点对的路径上的最近距离大于先前求得的最近距离则进行更新。

注意:可能两人的最近距离是0,在更新的时候要注意。

详细代码:

普通队列:

 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], rev[5]={1,0,3,2,4};
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[rev[d1]], c1 += dy[rev[d1]],
36         r2 += dx[rev[d2]], c2 += dy[rev[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

 

poj 1729 Jack and Jill (搜索,bfs)

标签:

原文地址:http://www.cnblogs.com/yyf2016/p/5789382.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!