POJ 731 Jack and Jill 【bfs搜索】【北大ACM/ICPC竞赛训练】

我日了啊,就是一道大水题。老师上课说二分那个最大最近距离,但实际上二分会T啊!!!!

直接正常的优先队列就完事了啊!!!

  1 #include<iostream>
  2 #include<cstring>
  3 #include<queue>
  4 #include<cmath>
  5 #include<vector>
  6 #include<iomanip>
  7 #include <stdio.h>
  8 using namespace std;
  9 
 10 int vis[31][31][31][31],n;
 11 char maze[35][35];
 12 int Jack_start_row,Jack_start_col,Jack_end_row,Jack_end_col;
 13 int Jill_start_row,Jill_start_col,Jill_end_row,Jill_end_col;
 14 int dx[4]={0,0,1,-1};
 15 int dy[4]={1,-1,0,0};
 16 char ophash[4]={'S','N','E','W'}; //对应S N E W
 17 struct point{
 18     int r,c;
 19     point(int r1=0,int c1=0): r(r1),c(c1) {}
 20 };
 21 
 22 struct node{
 23     point Jack,Jill;
 24     char opJack,opJill;//从上一个状态到这个状态的走法   == w代表已经又一个走到了,另一个的状态是在等 
 25     double dis;//一路上离得最近的一次 
 26     node(point j1=point(),point j2=point(),double d1=0,char o1=' ',char o2=' '): Jack(j1),Jill(j2),dis(d1),opJack(o1),opJill(o2) {}
 27     bool operator < (const node &n) const{
 28         return dis<n.dis;
 29     }
 30 }Prev[31][31][31][31];
 31 
 32 double find_dis(point n1,point n2){
 33     double d1 = abs(n1.c-n2.c);
 34     double d2 = abs(n1.r-n2.r);
 35     return sqrt(d1*d1+d2*d2);
 36 }
 37 
 38 void bfs(){//看能不能找到一条路使得两人都到学校且相隔【始终>=k】
 39     for(int i=1;i<=n;++i)
 40         for(int j=1;j<=n;++j)
 41             for(int k=1;k<=n;++k)
 42                 for(int m=1;m<=n;++m)
 43                     vis[i][j][k][m] = 0;
 44 
 45     priority_queue<node> q;
 46     point jack = point(Jack_start_row,Jack_start_col);
 47     point jill = point(Jill_start_row,Jill_start_col);
 48     q.push( node(jack,jill,find_dis(jack,jill),' ',' ') );
 49     vis[Jack_start_row][Jack_start_col][Jill_start_row][Jill_start_col]=1;
 50     
 51     while(!q.empty()){
 52         node n1 = q.top(); q.pop();
 53         Prev[n1.Jack.r][n1.Jack.c][n1.Jill.r][n1.Jill.c] = n1;
 54         if( n1.Jack.r==Jack_end_row && n1.Jack.c==Jack_end_col && n1.Jill.r==Jill_end_row && n1.Jill.c==Jill_end_col ) { cout<<fixed<<setprecision(2)<<n1.dis<<endl; return; };
 55         //如果jack已经到学校
 56         if(n1.Jack.r==Jack_end_row && n1.Jack.c==Jack_end_col){
 57             for(int i=0;i<4;i++){
 58                 int Jillr = n1.Jill.r + dy[i];
 59                 int Jillc = n1.Jill.c + dx[i];
 60                 char pos = maze[Jillr][Jillc];
 61                 char op2 = ophash[i];
 62                 double diss = find_dis( point(Jack_end_row,Jack_end_col),point(Jillr,Jillc) );
 63                 if( Jillr>=1 && Jillr<=n && Jillc>=1 && Jillc<=n && pos!='*' && pos!='S' && pos!='H' && !vis[Jack_end_row][Jack_end_col][Jillr][Jillc] ){
 64                     vis[Jack_end_row][Jack_end_col][Jillr][Jillc]=1;
 65                     q.push( node( point(Jack_end_row,Jack_end_col),point(Jillr,Jillc),min(diss,n1.dis),'w',op2) );
 66                 }
 67             }
 68         }
 69         //如果jill已经到学校 
 70         else if(n1.Jill.r==Jill_end_row && n1.Jill.c==Jill_end_col){
 71             for(int i=0;i<4;i++){
 72                 int Jackr = n1.Jack.r + dy[i];
 73                 int Jackc = n1.Jack.c + dx[i];
 74                 char pos = maze[Jackr][Jackc];
 75                 char op1 = ophash[i];
 76                 double diss = find_dis( point(Jill_end_row,Jill_end_col),point(Jackr,Jackc) );
 77                 if( Jackr>=1 && Jackr<=n && Jackc>=1 && Jackc<=n && pos!='*' && pos!='s' && pos!='h' && !vis[Jackr][Jackc][Jill_end_row][Jill_end_col] ){
 78                     vis[Jackr][Jackc][Jill_end_row][Jill_end_col]=1;
 79                     q.push( node( point(Jackr,Jackc),point(Jill_end_row,Jill_end_col),min(diss,n1.dis),op1,'w') );
 80                 }
 81             }
 82         }
 83         else{
 84             for(int i=0;i<4;i++){//枚举每一个Jack能走的
 85                 int Jackr = n1.Jack.r + dy[i];
 86                 int Jackc = n1.Jack.c + dx[i];
 87                 char pos=maze[Jackr][Jackc];
 88                 if( Jackr>=1 && Jackr<=n && Jackc>=1 && Jackc<=n && pos!='*' && pos!='s' && pos!='h'){
 89                     for(int j=0;j<4;j++){//枚举每个Jill能走的 
 90                         int Jillr = n1.Jill.r + dy[j];
 91                         int Jillc = n1.Jill.c + dx[j];
 92                         pos = maze[Jillr][Jillc];
 93                         char op1=ophash[i],op2=ophash[j];
 94                         double diss = find_dis( point(Jackr,Jackc),point(Jillr,Jillc) );
 95                         if( Jillr>=1 && Jillr<=n && Jillc>=1 && Jillc<=n && pos!='*' && pos!='S' && pos!='H' && !vis[Jackr][Jackc][Jillr][Jillc] ){
 96                             vis[Jackr][Jackc][Jillr][Jillc]=1;
 97                             q.push( node(point(Jackr,Jackc),point(Jillr,Jillc),min(diss,n1.dis),op1,op2) );
 98                         }    
 99                     }    
100                 } 
101             }
102         }
103     }    
104     return;
105 }
106 
107 
108 int main(){
109     //freopen("in.txt","r",stdin);
110      //freopen("out.txt","w",stdout);
111     std::ios::sync_with_stdio(false);
112     while(1){
113         cin>>n;
114         if(n==0) break;
115 
116 
117         for(int i=1;i<=n;i++)
118             for(int j=1;j<=n;j++){
119                 cin>>maze[i][j];
120                 if(maze[i][j]=='H'){ Jack_start_row=i; Jack_start_col=j; }
121                 else if(maze[i][j]=='S'){ Jack_end_row=i; Jack_end_col=j; }
122                 else if(maze[i][j]=='h'){ Jill_start_row=i; Jill_start_col=j; }
123                 else if(maze[i][j]=='s'){ Jill_end_row=i; Jill_end_col=j; }
124             }
125         
126         double d1 = abs(Jack_start_row-Jill_start_row), d2 = abs(Jack_start_col-Jill_start_col);
127         double d3 = abs(Jack_end_row-Jill_end_row), d4 = abs(Jack_end_col-Jill_end_col);
128         
129         double start = 0;     
130         double end = min( sqrt(d1*d1+d2*d2),sqrt(d3*d3+d4*d4) ); //他们两个最初和结束时的距离 
131         
132         bfs();
133         vector<char> ans1,ans2;
134         int p1=Jack_end_row,p2=Jack_end_col,p3=Jill_end_row,p4=Jill_end_col;
135         while( p1!=0 ){
136             node p = Prev[p1][p2][p3][p4];
137             char op1=p.opJack,op2=p.opJill;
138             if(op1!='w' && op1!=' ') ans1.push_back( op1 );
139             if(op2!='w' && op2!=' ') ans2.push_back( op2 );
140             if(op1==' ') break;//回到起点
141             //更新 p1 p2
142             if(op1=='S') p1-=1; 
143             else if(op1=='N') p1+=1;
144             else if(op1=='E') p2-=1;
145             else if(op1=='W') p2+=1;
146             //更新 p3 p4 
147             if(op2=='S') p3-=1; 
148             else if(op2=='N') p3+=1;
149             else if(op2=='E') p4-=1;
150             else if(op2=='W') p4+=1;
151         }        
152         //先jack后jill 
153         for(int i=ans1.size()-1;i>=0;i--) cout<<ans1[i]; cout<<endl;
154         for(int i=ans2.size()-1;i>=0;i--) cout<<ans2[i]; cout<<endl;
155         cout<<endl;
156     }
157 
158     return 0;    
159 }

 

转载于:https://www.cnblogs.com/ZhenghangHu/p/9389519.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值