poj3009——Curling 2.0

来源:互联网 发布:vba 数组赋值 编辑:程序博客网 时间:2024/06/06 12:56

题目大意:在有一些障碍的球场打冰球,只能向前后左右扔(不能扔对角线),球会一直按所扔方向走直到撞墙,撞墙时球停在墙的前一个格子处,并且墙消失,问最少需要扔多少次能让球从起始S走到目标G,次数不能超过10次,否则失败

输入:(可以有不超过100个的case,一个case即一个数据集,输入以0 0结束)

            第i个case的球场宽度w  高度h( 2 <= w <= 20, 1 <= h <= 20.)

            第i个case种第j行球场的布局情况(0代表空地 1代表障碍物 2代表S 3代表G)

输出:第i个case的最小扔球次数(如果失败无解则输出-1)

分析:dfs搜索

           球扔出去三种情况:到了G;撞了墙;直接扔出了球场

           注意在撞墙消除障碍物dfs之后要还原障碍物和步数

代码:转载自http://blog.csdn.net/fanxing1/article/details/6310037

  1. #include<stdio.h>  
  2. int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};  
  3. int ei,ej;  
  4. int map[25][25];  
  5. int w,h,steps,min;  
  6. #define MAX 99999999  
  7. void dfs(int si,int sj)  
  8. {  
  9.     int i,pi,pj;  
  10.     if(steps>=10) return ;  
  11.   
  12.     for(i=0;i<4;i++)  
  13.     {         
  14.         pi=si,pj=sj;  
  15.         while(1)  //越界或到达G或撞墙这三种情况满足一个就得退出while循环,因为不能再接着沿着这个方向走了
  16.         {  
  17.             pi+=dir[i][0];  
  18.             pj+=dir[i][1];  
  19.             if(pi<=0||pi>h||pj<=0||pj>w) break;//如果越界,选择其他方向  
  20.             if(pi==ei&&pj==ej)   
  21.             {  
  22.                 steps++;  
  23.                 if(min>steps) min=steps;  
  24.                 steps--;  
  25.                 return;  
  26.             }  
  27.             else if(map[pi][pj]==1)//如果遇到障碍物  
  28.             {  
  29.   
  30.                 if(pi-dir[i][0]!=si||pj-dir[i][1]!=sj)//如果不是本次dfs的起点
  31.                 {  
  32.                     map[pi][pj]=0;//消除障碍物  
  33.                     steps++;//前进一步  
  34.                     dfs(pi-dir[i][0],pj-dir[i][1]);//递归查找该点到终点的最小步数  
  35.                     map[pi][pj]=1;//还原障碍物  
  36.                     steps--;//还原步数  
  37.                 }  
  38.                 break;  
  39.             }  
  40.         }  
  41.     }  
  42. }         
  43. int main()  
  44. {  
  45.     int si,sj,i,j;  
  46.     while(scanf("%d%d",&w,&h)==2&&(w||h))  
  47.     {  
  48.         for(i=1;i<=h;i++)//输入并找到起点和终点  
  49.             for(j=1;j<=w;j++)  
  50.             {  
  51.                 scanf("%d",&map[i][j]);  
  52.                 if(map[i][j]==2)  
  53.                     si=i,sj=j;  
  54.                 else if(map[i][j]==3)  
  55.                     ei=i,ej=j;  
  56.             }  
  57.             min=MAX;//记录最小步数  
  58.             steps=0;//初始化步数  
  59.             dfs(si,sj);//深搜  
  60.             if(min==MAX) puts("-1");  
  61.             else printf("%d/n",min);  
  62.     }  
  63.     return 0;