• 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
    ", 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("
    ");
    45     }
    46     printf("
    ");
    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
    ", 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("
    ");
     48     }
     49     printf("
    ");
     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("
    ");
    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
    ", sqrt(mx - 1));
    141         print_path();
    142     }
    143 
    144     return 0;
    145 }
    View Code
  • 相关阅读:
    GIT版本控制工具使用
    Django一些常用settings设置
    排序算法
    pipenv简单使用
    scrapy以及redis简单应用
    GIT上传本地项目到Github
    Requests爬虫和scrapy框架多线程爬虫
    Django分页组件
    关于 KendoUI Grid的默认选中的一些事
    关于在笔记本使用eclipseIDE工具进行开发时怎么切换eclipse输入状态
  • 原文地址:https://www.cnblogs.com/yyf2016/p/5789382.html
Copyright © 2020-2023  润新知