zoukankan      html  css  js  c++  java
  • csu

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1566

    题意还是蛮难懂的,至少对于我来说,需要认真读题。

    输入矩阵的每一个数字换成2进制后,顺时针围一圈,用1表示墙,0表示空,这样就可以表示出一个迷宫,现在就是判断这个迷宫属于4种类型中哪种类型。

    参考了 大神博客。构图很难,并且想法跟以往的题都不一样。是一个好题。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cmath>
      4 #include <vector>
      5 #include <cstring>
      6 #include <string>
      7 #include <algorithm>
      8 #include <string>
      9 #include <set>
     10 #include <functional>
     11 #include <numeric>
     12 #include <sstream>
     13 #include <stack>
     14 #include <map>
     15 #include <queue>
     16 #pragma comment(linker, "/STACK:102400000,102400000")
     17 #define CL(arr, val)    memset(arr, val, sizeof(arr))
     18 
     19 #define ll long long
     20 #define inf 0x7f7f7f7f
     21 #define lc l,m,rt<<1
     22 #define rc m + 1,r,rt<<1|1
     23 #define pi acos(-1.0)
     24 
     25 #define L(x)    (x) << 1
     26 #define R(x)    (x) << 1 | 1
     27 #define MID(l, r)   (l + r) >> 1
     28 #define Min(x, y)   (x) < (y) ? (x) : (y)
     29 #define Max(x, y)   (x) < (y) ? (y) : (x)
     30 #define E(x)        (1 << (x))
     31 #define iabs(x)     (x) < 0 ? -(x) : (x)
     32 #define OUT(x)  printf("%I64d
    ", x)
     33 #define lowbit(x)   (x)&(-x)
     34 #define Read()  freopen("a.txt", "r", stdin)
     35 #define Write() freopen("b.txt", "w", stdout);
     36 #define maxn 1000000000
     37 #define N 2510
     38 #define mod 1000000000
     39 using namespace std;
     40 
     41 int n,m;
     42 int num[55][55],vis[55][55];
     43 int dir[4][3]={1,0,2,-1,0,8,0,1,4,0,-1,1};
     44 //这里必须要对应  是为了防止往回走
     45 struct point
     46 {
     47     int a,b;
     48 };
     49 int main()
     50 {
     51    //freopen("a.txt","r",stdin);
     52     char s[55];
     53     int x,y,nx,ny;
     54     while(~scanf("%d%d",&n,&m))
     55     {
     56         if(!n&&!m) break;
     57         for(int i=1;i<=n;i++)
     58         {
     59             scanf("%s",s+1);
     60             for(int j=1;j<=m;j++)
     61             {
     62                 if(s[j]>='0'&&s[j]<='9') num[i][j]=s[j]-'0';
     63                 else num[i][j]=s[j]-'A'+10;
     64                 num[i][j]=~num[i][j];   //读入之后 按位取反 ,能走的变成1 不能走的变成0
     65             }
     66         }
     67         x=0;   //找出  起点和终点
     68         for(int i=1;i<=n;i++)  //第一列或者第m列 看左右边界
     69         {
     70             if(num[i][1]&1)  //代表表示 num[i][1]的四位2进制数中最后一位是1 代表有缺口
     71             {
     72                 if(!x) x=i,y=1;
     73                 else nx=i,ny=1;
     74             }
     75             if(num[i][m]&4)
     76             {
     77                 if(!x) x=i,y=m;
     78                 else nx=i,ny=m;
     79             }
     80         }
     81         for(int i=1;i<=m;i++)  //同上,看上下边界
     82         {
     83             if(num[1][i]&8)
     84             {
     85                 if(!x) x=1,y=i;
     86                 else nx=1,ny=i;
     87             }
     88             if(num[n][i]&2)
     89             {
     90                 if(!x) x=n,y=i;
     91                 else nx=n,ny=i;
     92             }
     93         }
     94      //   printf("%d %d %d %d
    ",x,y,nx,ny);
     95         memset(vis,0,sizeof(vis));
     96         int mul=0;
     97         queue<point>que;
     98         point now,next;
     99         now.a=x,now.b=y;
    100         vis[now.a][now.b]=16;
    101         que.push(now);
    102         while(!que.empty())   //扩展所有能到达的点
    103         {
    104             next=que.front();que.pop();
    105             for(int i=0;i<4;i++)
    106             {
    107                 if(vis[next.a][next.b]==dir[i][2]) continue; //已经访问过,防止往回走,
    108                 if(num[next.a][next.b]&dir[i][2])  //该方向能访问
    109                 {
    110                     now.a=next.a+dir[i][0];
    111                     now.b=next.b+dir[i][1];
    112                     if(now.a>=1&&now.a<=n&&now.b>=1&&now.b<=m)
    113                     {
    114                         if(vis[now.a][now.b]) mul=1;  //多次到达同一个点
    115                         else
    116                         {
    117                             if(dir[i][2]==4) vis[now.a][now.b]=1; //赋值相反方向的值给vis,防止往回走,跟上面的判断对应
    118                             else if(dir[i][2]==1) vis[now.a][now.b]=4;
    119                             else if(dir[i][2]==8) vis[now.a][now.b]=2;
    120                             else if(dir[i][2]==2) vis[now.a][now.b]=8;
    121                             que.push(now);
    122                         }
    123                     }
    124                 }
    125             }
    126         }
    127         if(vis[nx][ny]) //能到出口
    128         {
    129             bool flag=0;
    130             for(int i=1;i<=n;i++)
    131             {
    132                 for(int j=1;j<=m;j++)
    133                     if(!vis[i][j])
    134                     {
    135                         //printf("%d %d
    ",i,j);
    136                         flag=1;
    137                         break;
    138                     }
    139                 if(flag) break;
    140             }
    141             if(flag) printf("UNREACHABLE CELL
    "); //有点不能到达
    142             else
    143             {
    144                 if(mul) printf("MULTIPLE PATHS
    "); //多次到达
    145                 else printf("MAZE OK
    "); //只有一条路径
    146             }
    147         }
    148         else printf("NO SOLUTION
    "); //没有路径
    149     }
    150     return 0;
    151 }
  • 相关阅读:
    [SCOI2015]国旗计划
    [SCOI2015]小凸玩矩阵
    点分治复习笔记
    [HNOI2014]米特运输
    [HNOI2015]接水果
    [HEOI2016/TJOI2016]游戏
    为什么验证集的loss会小于训练集的loss?
    转载GPU并行计算
    深度学习图像标注工具汇总(转载)
    你理解了吗?
  • 原文地址:https://www.cnblogs.com/nowandforever/p/4542667.html
Copyright © 2011-2022 走看看