标签:
原题网址: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 }
poj 1729 Jack and Jill (搜索,bfs)
标签:
原文地址:http://www.cnblogs.com/yyf2016/p/5789382.html