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 }

 

转载于:https://www.cnblogs.com/marlenemizuno/p/6993909.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值