Poj 1024
判断给定的路径是否是迷宫的唯一最短路径,判断迷宫是否有墙多余
bfs计算出每个点分别到起点和终点的最短路径
路径是否是迷宫的唯一最短路径:将路径上的点和墙两侧的点标记,查看是否有非标记的点到起点和终点之和小于等于给定路径长度
是否有墙多余:设墙两侧的点分别为a、b,若a到起点的距离与b到终点的距离大于路径长度并且a到终点的距离与b到起点的距离大于路径长度,则墙多余
若有封闭区间(到起点和终点距离都为0)则必有墙多余。
1 #include<iostream> 2 #include<cstring> 3 #include<string> 4 using namespace std; 5 6 struct point{ 7 int x; 8 int y; 9 }; 10 11 struct wall{ 12 int x1,y1; 13 int x2,y2; 14 }; 15 16 const int MAX=100; 17 18 int T;//案例个数 19 int w,h;//迷宫宽高 20 int n;//墙的个数 21 int marked[MAX][MAX]; 22 int dis1[MAX][MAX];//到起点的距离 23 int dis2[MAX][MAX];//到终点的距离 24 bool is_true; 25 string path;//路径 26 point end;//终点位置 27 point begin; 28 wall bar[MAX*MAX]; 29 30 void bfs(point p,int dis[][MAX]){ 31 int vis[MAX][MAX]={0};//标记 32 point s[MAX*MAX]; 33 memset(s,0,sizeof(s)); 34 vis[p.x][p.y]=1; 35 dis[p.x][p.y]=0; 36 int head=0,tail=0; 37 s[tail].x=p.x;s[tail].y=p.y; 38 tail++; 39 while(head<tail){ 40 int x=s[head].x; 41 int y=s[head].y; 42 int px[]={0,0,1,-1}; 43 int py[]={1,-1,0,0}; 44 head++; 45 for(int i=0;i<4;i++){ 46 if(vis[x+px[i]][y+py[i]]==1||x+px[i]<0||x+px[i]>=w||y+py[i]<0||y+py[i]>=h) 47 continue; 48 bool flag=false;//两格中间无墙 49 for(int j=0;j<n;j++){ 50 if((bar[j].x1==x&&bar[j].y1==y&&bar[j].x2==x+px[i]&&bar[j].y2==y+py[i])||(bar[j].x2==x&&bar[j].y2==y&&bar[j].x1==x+px[i]&&bar[j].y1==y+py[i])){ 51 flag=true; 52 break; 53 } 54 } 55 if(flag){ 56 continue; 57 } 58 vis[x+px[i]][y+py[i]]=1; 59 s[tail].x=x+px[i]; 60 s[tail].y=y+py[i]; 61 tail++; 62 dis[x+px[i]][y+py[i]]=dis[x][y]+1; 63 } 64 } 65 } 66 67 int main(){ 68 cin>>T; 69 begin.x=0;begin.y=0; 70 while(T--){ 71 cin>>w>>h; 72 memset(marked,0,sizeof(marked)); 73 cin>>path; 74 end.x=0;end.y=0; 75 marked[end.x][end.y]=1; 76 for(int i=0;i<path.length();i++){ 77 switch(path[i]){ 78 case 'U': 79 end.y++; 80 break; 81 case 'D': 82 end.y--; 83 break; 84 case 'L': 85 end.x--; 86 break; 87 case 'R': 88 end.x++; 89 break; 90 } 91 marked[end.x][end.y]=1; 92 } 93 cin>>n; 94 for(int i=0;i<n;i++){ 95 cin>>bar[i].x1>>bar[i].y1>>bar[i].x2>>bar[i].y2; 96 marked[bar[i].x1][bar[i].y1]=1; 97 marked[bar[i].x2][bar[i].y2]=1; 98 } 99 memset(dis1,0,sizeof(dis1)); 100 memset(dis2,0,sizeof(dis2)); 101 bfs(begin,dis1); 102 bfs(end,dis2); 103 is_true=true; 104 for(int i=0;i<w;i++){ 105 for(int j=0;j<h;j++){ 106 if(marked[i][j]==0&&dis1[i][j]+dis2[i][j]<=path.length()){ 107 is_true=false; 108 break; 109 } 110 } 111 }//判断是否为最小路径 112 if(!is_true){ 113 cout<<"INCORRECT"<<endl; 114 continue; 115 } 116 for(int i=0;i<n;i++){ 117 if(dis1[bar[i].x1][bar[i].y1]+dis2[bar[i].x2][bar[i].y2]>path.length()&&dis2[bar[i].x1][bar[i].y1]+dis1[bar[i].x2][bar[i].y2]>path.length()){ 118 is_true=false; 119 break; 120 } 121 if((dis1[bar[i].x1][bar[i].y1]==0&&dis2[bar[i].x1][bar[i].y1]==0)||(dis1[bar[i].x2][bar[i].y2]==0&&dis2[bar[i].x2][bar[i].y2]==0)){ 122 is_true=false; 123 break; 124 }//有封闭区间 125 } //判断是否有墙多余 126 if(!is_true){ 127 cout<<"INCORRECT"<<endl; 128 continue; 129 } 130 else{ 131 cout<<"CORRECT"<<endl; 132 } 133 } 134 }