zoukankan      html  css  js  c++  java
  • [noip模拟]难缠的值周生<宽搜>

    难缠的值周生 
    【问题描述】 
    小 P 上学总是迟到,迟到了以后常常会被值周生发现。被值周生发现就会给
    他所在的班级扣分,被扣了分不免要挨班主任的训,这令小 P 很不爽。不过,聪
    明的他经过观察发现,值周生通常会站在固定的位置,并且他们都很笨,只会向
    固定的同一个方向看。于是小 P 经过潜心研究,把值周生的站位和方向以及学校
    的地形绘成一张地图,你的任务是编写一个程序,帮助小 P 找出一条路从大门到
    达教室并且不被值周生发现。 
     
    【输入文件】 
    输入文件的第一行是两个整数 N,G,代表学校是一个N × N的正方形,其
    中有 G 个值周生。 
    接下来输入一个 N  ×  N 的矩阵,代表学校。其中.代表空地,X(大写英文字
    母)代表墙,E 代表学校的大门,小 P 将从这里进入学校,C 代表教室,小 P 到
    达这里就胜利了。数字代表值周生,数字的值代表值周生的编号,显然值周生不
    能穿墙透视,但是小 P 也不能翻墙或者站到墙上去。 
    接下来有 G 行,每行包含一个数字Gi 和一个字母,代表第 Gi 个值周生的朝
    向。其中 N 表示北,S 表示南,E 表示东,W 表示西。显然,如果你撞上值周
    生(走到值周生所在的格子上),也会被值周生发现。 
     
    【输出文件】 
    输出文件包含任意一个行走方案,每行一个字母,表示小P 每步走的方向。
    如果无论小P 怎么走都不能不被值周生发现的走到教室,则输出一行整数-1。 
     
    【样例输入】 
    5 3 
    ..E.1 
    ...XX 
    .2.X. 
    .C.X. 
    ...X3 
    1 E 
    2 E 
    3 W

     

    没错这样一道题确实是冬令营的题,没错而且方法就是你第一眼看出的bfs

    但是,但是,我还是错了很久,然而,当我拿到数据的时候,千言万语汇成一句话:吔屎了出题人

    首先我们看一个史上最短的AC代码

    1 #include<cstdio>
    2 int main(){
    3     freopen("guard.in","r",stdin);
    4     freopen("guard.out","w",stdout);
    5     puts("-1");}
    View Code

    没错所有数据的答案是-1,所以就算你bfs再精妙,只要你忘记输出-1,那就GG

     

    然后更有趣的地方来了

    我来展示一波数据3

    10 2
    ....G.....
    2.........
    ..........
    ..1.......
    ..........
    ....C.....
    ..........
    ..........
    ..........
    ..........
    1 N
    2 E

    看出什么没,看出什么没????没错,题干所说的E不见了,好神奇是不是,所以你的程序就会一直少读入一个或者找错起点,是不是很神奇

    所以吔屎了出题人QAQ

    -------------------------------------------------------------------

    好了正经点讲一讲题解,这题的做法就是BFS,特殊处理就是不要用STL的队列,手写一个队列记录一个前驱,另外就是处理视线重合和围墙两种不同的情况

    然后就没了

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<iostream>
      5 #include<queue>
      6 #include<cstdlib>
      7 #include<cmath>
      8 #define maxn 40
      9 using namespace std;
     10 
     11 struct node{
     12     int x,y,pre;
     13 };//d:0=N 1=S 2=W 3=E
     14 const int dx[]={-1,1,0,0},dy[]={0,0,-1,1};
     15 int n,m,sx,sy,fx,fy,g,tot;
     16 int map[maxn][maxn],gx[maxn],gy[maxn],ans[maxn];
     17 node q[500005];
     18 
     19 int read(){
     20     int xx=0,ff=1;char ch=getchar();
     21     while(ch<'0'||ch>'9'){if(ch=='-')ff=-1;ch=getchar();}
     22     while(ch>='0'&&ch<='9'){xx=xx*10+ch-'0';ch=getchar();}
     23     return xx*ff;
     24 }
     25 
     26 int check(int x,int y){
     27     if(x<1||x>n||y<1||y>n)return false;
     28     return true;
     29 }
     30 
     31 void del(int num,int dir){
     32     int nx=gx[num],ny=gy[num];
     33     while(check(nx,ny)){
     34         map[nx][ny]=1;
     35         nx+=dx[dir];ny+=dy[dir];
     36         if(map[nx][ny]==2)break;
     37     }
     38 }
     39 
     40 void fre(){
     41     freopen("guard.in","r",stdin);
     42     freopen("guard.out","w",stdout);
     43 }
     44 
     45 void init(){
     46         n=read();g=read();
     47     for(int i=1;i<=n;i++){
     48         for(int j=1;j<=n;j++){
     49             char ch=getchar();int gg;
     50             while(ch!='G'&&ch!='E'&&ch!='.'&&ch!='C'&&(ch<'0'||ch>'9')&&ch!='X')ch=getchar();
     51             if(ch=='.')continue;
     52             if(ch=='X')map[i][j]=2;
     53             if(ch=='C')fx=i,fy=j;
     54             if(ch=='E'||ch=='G')sx=i,sy=j;
     55             if(ch>='1'&&ch<='9'){
     56                 gg=ch-'0';gx[gg]=i;gy[gg]=j;
     57             }
     58         }
     59     }
     60     for(int i=1;i<=g;i++){
     61         int gg;char ch;
     62         gg=read();ch=getchar();
     63         while(ch!='N'&&ch!='W'&&ch!='S'&&ch!='E')ch=getchar();
     64         if(ch=='N'){del(gg,0);}
     65         if(ch=='S'){del(gg,1);}
     66         if(ch=='W'){del(gg,2);}
     67         if(ch=='E'){del(gg,3);}
     68     }
     69 }
     70 
     71 void print(int r){   
     72     while(q[r].pre){  
     73         int l=q[r].pre;  
     74         if(q[r].x==q[l].x){  
     75             if(q[r].y>q[l].y)  
     76                 ans[++tot]='E';  
     77             else  ans[++tot]='W';  
     78         }else{  
     79             if(q[r].x<q[l].x)  
     80                 ans[++tot]='N';  
     81             else  ans[++tot]='S';  
     82         }r=l;  
     83     }  
     84     for(int i=tot;i>=1;i--){  
     85         printf("%c
    ",ans[i]);  
     86     }  
     87 }  
     88 
     89 void bfs(int ssx,int ssy){
     90     q[1]=(node){ssx,ssy,0};
     91     int l=0,r=0;r++;
     92     while(l<r){
     93         l++;
     94         node u=q[l];
     95         map[u.x][u.y]=1;
     96         if(u.x==fx&&u.y==fy){
     97             print(l);return;
     98         }
     99         for(int i=0;i<=3;i++){
    100             int nx=u.x+dx[i];
    101             int ny=u.y+dy[i];
    102             if(!check(nx,ny))continue;
    103             if(map[nx][ny]==0){
    104                 map[nx][ny]=1;
    105                 r++;q[r]=(node){nx,ny,l};
    106                 if(nx==fx&&ny==fy){
    107                     print(r);return;
    108                 }
    109             }
    110         }    
    111     }
    112     puts("-1");
    113 }
    114 
    115 int main(){
    116     fre();
    117     init();
    118     if(map[sx][sy]==1){puts("-1");return 0;}
    119     bfs(sx,sy); 
    120 }
    View Code

    我的代码有些步骤可能是多余的,因为之前我显示的是超时,所以我把所有可能降低一丢时间复杂度的地方都魔改了,所以不要在意细节了

     

  • 相关阅读:
    poj 1201 Intervals 差分约束系统
    poj 3237 Tree 树链剖分+线段树
    hdu 2256 Problem of Precision 构造整数 + 矩阵快速幂
    hdu 5451 Best Solver 矩阵循环群+矩阵快速幂
    hdu 5769 Substring 后缀数组 + KMP
    hdu 5755 2016 Multi-University Training Contest 3 Gambler Bo 高斯消元模3同余方程
    hdu 5690 2016"百度之星"
    hdu 5738 2016 Multi-University Training Contest 2 Eureka 计数问题(组合数学+STL)
    hdu 5719 BestCoder 2nd Anniversary B Arrange 简单计数问题
    hdu 5720 BestCoder 2nd Anniversary Wool 推理+一维区间的并
  • 原文地址:https://www.cnblogs.com/Danzel-Aria233/p/7766706.html
Copyright © 2011-2022 走看看