我日了啊,就是一道大水题。老师上课说二分那个最大最近距离,但实际上二分会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 }