hdu 1728 逃离迷宫(最小转弯)

每次将不转弯能到的点全部标记(标记转弯次数)接着也只能由这些点扩展了,,将它们能到的所有点标记,同时转弯次数加1。
//暴力搜索非递归
#include<stdio.h>
#include<string.h>
int n,m;
int book[120][120];
char a[120][120];
int dfs(int x,int y,int c){
 int flag=0;//判断是否标记地图,没再标记就证明标记工作已经完成
 for(int i=x+1;i<=n;i++)  //右
 if(book[i][y]==0){book[i][y]=c;flag=1;}  //只标记没标记过的,若标记跳过继续标记.
 else if(book[i][y]==-1) break;
 for(int i=x-1;i>=1;i--)  //左
 if(book[i][y]==0){book[i][y]=c;flag=1;}
 else if(book[i][y]==-1) break;
  for(int i=y+1;i<=m;i++) //上
 if(book[x][i]==0){book[x][i]=c;flag=1;}
 else if(book[x][i]==-1) break;
 for(int i=y-1;i>=1;i--) //下
 if(book[x][i]==0){book[x][i]=c;flag=1;}
 else if(book[x][i]==-1) break;
 return flag;
}
int main(){
  int t;
  scanf("%d",&t);
  while(t--){
     scanf("%d%d",&n,&m);
     for(int i=1;i<=n;i++)
      scanf("%s",a[i]+1);
    int startx,starty,endx,endy,k;
    scanf("%d%d%d%d%d",&k,&starty,&startx,&endy,&endx);
    if(startx==endx&&starty==endy){printf("yes\n");continue;} //可能的数据 
    if(a[endx][endy]=='*'){printf("no\n");continue;} //可能的数据
    memset(book,0,sizeof(book));

    for(int i=1;i<=n;i++)
     for(int j=1;j<=m;j++)
        if(a[i][j]=='*') book[i][j]=-1; //传地图到book二维数组

    book[startx][starty]=1;  //初始化
     dfs(startx,starty,1);  //初始化
    int c=1;               //初始化
    while(1){              //开始进入循环
            int flag=0;
        for(int i=1;i<=n;i++)
         for(int j=1;j<=m;j++)
        {
            if(book[i][j]==c){if(dfs(i,j,c+1)) flag=1;}
        }
        if(flag==0) break;
        c+=1;
    }
    if(book[endx][endy]<=k+1&&book[endx][endy]!=0){printf("yes\n");}//book[endx][endy]!=0条件让我wr了好久
    else printf("no\n");
 }
return 0;
}

第二次碰到这题,没想着去暴力,wr的很惨,标记了8个方向,每个格的入和出各四个方向,下次补下。

思路:book数组标由标记走没走过改为标记拐弯数即可,用优先队列优先最小拐弯数的点扩展。(只是写法不同,思路延续的还是上面代码)

#include<bits/stdc++.h>
using namespace std;
const int N=100,inf=9999999;
char a[N+10][N+10];
int book[N+10][N+10];
struct node
{
    int x,y,dir,k;
   friend bool operator < (node p,node q){return p.k>q.k;}
};
priority_queue<node>que,pq;
int bfs(int n,int m,int kk,int startx,int starty,int endx,int endy)
{  //printf("&&%d %d %d %d %d\n",startx,starty,endx,endy,kk);
    int next[5][2]={{0,0},{0,1},{1,0},{0,-1},{-1,0}};
    for(int i=1;i<=n;i++)
     for(int j=1;j<=m;j++)
       book[i][j]=inf;
       while(!que.empty()) que.pop();
       node temp;temp.x=startx,temp.y=starty,temp.dir=0,temp.k=0;
       que.push(temp);
       while(!que.empty())
       {
         node temp1=que.top();
         //printf("=%d %d %d %d\n",temp1.x,temp1.y,temp1.dir,temp1.k);
         que.pop();
         for(int i=1;i<=4;i++)
         {
             int tx=temp1.x,ty=temp1.y,dir=temp1.dir,k=temp1.k;
             tx+=next[i][0],ty+=next[i][1];
             if(tx<1||tx>n||ty<1||ty>m||a[tx][ty]=='*') continue;
             if((dir==1&&i==3)||(dir==2&&i==4)||(dir==3&&i==1)||(dir==4&&i==2))continue;
             if(dir==0) {dir=i;}
             if(dir!=i) {k+=1;dir=i;}
             //printf("tx=%d ty=%d dir=%d k=%d %d\n",tx,ty,dir,k,book[tx][ty]);
             if(k>kk||k>book[tx][ty]) continue;
             if(tx==endx&&ty==endy){return 1;}
             book[tx][ty]=k;
             node temp2;temp2.x=tx,temp2.y=ty,temp2.k=k,temp2.dir=dir;
             que.push(temp2);
         }
       }
       return 0;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%s",a[i]+1);
        int k,startx,starty,endx,endy;
        scanf("%d%d%d%d%d",&k,&starty,&startx,&endy,&endx);
        if(startx==endx&&starty==endy){printf("yes\n");continue;}
        int flag=bfs(n,m,k,startx,starty,endx,endy);
        if(flag) printf("yes\n");
        else printf("no\n");
    }
    return 0;
}

再次遇到相关题目选择了很暴力的广搜

思路:book数组用来计数,无标记的广搜直到转弯超过1次终止,等同深搜。做法很危险,要是转5次10次呢.(该代码就危险了,额,快超时了600多)

没深刻理解上面正解原理,这类题采用暴力原理,优先的写法,思路对代码实现应变性强.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
const int inf=9999999;
int n,m,num;
char a[60][60];
int book[60][60];
struct node
{
    int x,y,k,dir;
};
queue<node>que;
int bfs(int startx,int starty)
{
    int u=0;
    memset(book,0,sizeof(book));
    int next[5][2]={0,0,0,1,1,0,0,-1,-1,0};
    while(!que.empty()) que.pop();
    node temp;temp.x=startx,temp.y=starty,temp.k=0,temp.dir=0;
    que.push(temp);
    book[startx][starty]=1;
    u++;
    while(!que.empty())
    {
        node temp1=que.front();
        que.pop();
        for(int i=1;i<=4;i++)
        {
            int tx=temp1.x+next[i][0],ty=temp1.y+next[i][1],k=temp1.k,dir=temp1.dir;
            if(tx<1||tx>n||ty<1||ty>m||a[tx][ty]=='W') continue;
            if(dir==0) dir=i;
            if(i==1&&dir==3||i==2&&dir==4||i==3&&dir==1||i==4&&dir==2) continue;
            if(dir!=i){dir=i;k++;}
            if(k>=2){continue;}
            if(!book[tx][ty]){book[tx][ty]=1;u++;}
            node temp2;temp2.x=tx,temp2.y=ty,temp2.k=k,temp2.dir=dir;
            que.push(temp2);
        }
    }
    if(u==num) return 1;
    return 0;
}
int main()
{
     while(scanf("%d%d",&n,&m)!=EOF)
     {
         for(int i=1;i<=n;i++) scanf("%s",a[i]+1);
         num=0;
         for(int i=1;i<=n;i++)
          for(int j=1;j<=m;j++)
            if(a[i][j]=='B')
            {
                num++;
            } 
            int flag=0;
        for(int i=1;i<=n;i++)
         for(int j=1;j<=m;j++)
           if(!flag&&a[i][j]=='B')
           {
               if(bfs(i,j)==0){flag=1;break;}
           }
           if(flag) printf("NO\n");
           else printf("YES\n");
     }
    return 0;
}


Convex Shape CodeForces - 275B
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值