Gym

来源:互联网 发布:matlab 随机字符串数组 编辑:程序博客网 时间:2024/06/16 01:21

http://codeforces.com/gym/100971/problem/J
搜索姿势有待提高。。
给定两个机器人1 和2的位置,问你可否让这俩货换位置,已知俩货不能同时在一个地方。。
我的思路:dfs两次路径。如果都相同,说明只有一条路,否则说明有两条,然后再一条路的情况下判断t型路。。
dfs找路完全是随机的。。可能把所有的都遍历了也可能到达了其他就结束了。。这个想法完全想当然。。

看的题解:bfs,判断是否连通。如果有的话,判断情况,
如果存在一个t型点,那么一定可以。
否则判断终点数。
一条路径下不可以(并且没有t型点)的时候端点为2
有多条时为0.。
还有别人写的 dfs代码,值得好好学习。。

直接用char数组,说数组开的太大了。。。只好用string数组阴奉阳违之。。

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <queue>using namespace std;/*1 先广搜一下,如果搜不到肯定不是。然后分为三种情况 1  出现t字型插口,肯定可以2 出现一个线的情况,*/const int maxn=200001;vector<bool>vis[maxn];int fx[4][2]={{1,0},{-1,0},{0,1},{0,-1}};string a[maxn];int m,n;int bfs(int a1,int b1){      //memset(vis,false,sizeof(vis));      for(int i=1;i<=m;i++)      {  for(int j=0;j<n;j++)          vis[i].push_back(0);      }      vis[a1][b1]=true;      queue<pair<int,int> >q;      q.push(make_pair(a1,b1));      while(!q.empty())      {    pair<int ,int >u=q.front();            q.pop();            for(int i=0;i<4;i++)            {   int x2=u.first+fx[i][0];                int y2=u.second+fx[i][1];                 if(x2>=1&&x2<=m&&y2>=0&&y2<n&&a[x2][y2]!='#'&&!vis[x2][y2])                     {q.push(make_pair(x2,y2));                      vis[x2][y2]=true;                     }            }      }return 0;}int main(){  int ux,uy,vx,vy;   char cc;     cin>>m>>n;     //a[0].push_back("1");     a[0]='1';          for(int i=1;i<=m;i++)        {  //a[i].push_back("1");            //for(int j=0;j<=n;j++)           cin>>a[i];             //a[i].push_back(cc);             //cin>>a[i][j];           for(int j=0;j<n;j++)           if(a[i][j]=='1')           {ux=i;uy=j;}           else if(a[i][j]=='2')             {vx=i;vy=j;}        }       bfs(ux,uy);       /*for(int i=1;i<=m;i++)       {{for(int j=1;j<=n;j++)          if(vis[i][j])            cout<<"1 ";          else            cout<<"0 ";       }        cout<<endl;       }*/       //cout<<"1"<<endl;       if(!vis[vx][vy])       {  puts("NO");return 0;       }       else       {   int tt=0;           bool flag=false;            for(int i=1;i<=m&&!flag;i++)             for(int j=0;j<n&&!flag;j++)             {   if(vis[i][j])                 {   int ans=0;                     for(int x=0;x<4;x++)                     {   int x1=fx[x][0]+i;                         int y1=fx[x][1]+j;                          if(a[x1][y1]!='#'&&x1>=1&&x1<=m&&y1>=0&&y1<n)                             ans++;                     }                     if(ans>2) flag=true;                           else if(ans==1) tt++;                 }             }            if(flag)                puts("YES");            else {if(tt==2)              puts("NO");              else if(tt==0)                puts("YES");              }       }    return 0;}
#include<cstdio>#define N 200005int n,m,ux,uy,ax,ay,a[N],u[N],ck,ans,fx[4]= {1,-1,0,0},fy[4]= {0,0,1,-1};char c;void dfs(int x,int y,int s){    if(x==ux&&y==uy&&s>2||x==ax&&y==ay)//走回起点(s是第几步)或走到终点        ans++;    if(u[x*m-m+y]||ans>2||ans&&ck)return;    u[x*m-m+y]=1;    int r=0;    for(int i=0;i<4;i++){        int nx=x+fx[i];        int ny=y+fy[i];        if(nx&&nx<=n&&ny&&ny<=m&&a[nx*m-m+ny]){            r++;//点的度            if(r>2)ck=1;            dfs(nx,ny,s+1);        }    }}int main(){    scanf("%d%d ",&n,&m);    for(int i=1; i<=n; i++)    {        for(int j=1; j<=m; j++)        {            c=getchar();            if(c!='#')                a[i*m-m+j]=1;            if(c=='1')            {                ux=i;                uy=j;            }            else if(c=='2')            {                ax=i;                ay=j;            }        }        getchar();    }    dfs(ux,uy,0);    if(ans>2||ans&&ck)printf("YES");    else printf("NO");    return 0;}