zoukankan      html  css  js  c++  java
  • 湖南省第6届程序大赛第6题 Biggest Number

    Problem F

    Biggest Number

    You have a maze with obstacles and non-zero digits in it:

                           

    You can start from any square, walk in the maze, and finally stop at some square. Each step, you may only walk into one of the four neighbouring squares (up, down, left, right) and you cannot walk into obstacles or walk into a square more than once. When you finish, you can get a number by writing down the digits you encounter in the same order as you meet them. For example, you can get numbers 9784, 4832145 etc. The biggest number you can get is 791452384, shown in the picture above.

    Your task is to find the biggest number you can get.

    Input

    There will be at most 25 test cases. Each test begins with two integers R and C (2<=R,C<=15, R*C<=30), the number of rows and columns of the maze. The next R rows represent the maze. Each line contains exactly C characters (without leading or trailing spaces), each of them will be either '#' or one of the nine non-zero digits. There will be at least one non-obstacle squares (i.e. squares with a non-zero digit in it) in the maze. The input is terminated by a test case with R=C=0, you should not process it.

    Output

    For each test case, print the biggest number you can find, on a single line.

    Sample Input

    Output for the Sample Input

    3 7

    ##9784#

    ##123##

    ##45###

    0 0

    791452384

     这道题目的话,就是让你输入的是n行m列。只有数字是可以走的,你可以从任何一个位置开始,你路过的地方的数字序列为aa[],要求输出序列比较最大的。

    题意是很明确的搜索,但是问题是时间。如果我每一个地方都进行一次dfs或者bfs的话,毫无疑问,肯定会超时。所以我们的思路应该放在如何去剪枝,如何去

    优化搜索的时间。最后的做法就是从每一个可以出发的地方都遍历一次,在中间加上剪枝就可以过了。

      1 #include <cstdio>
      2 #include <cstring>
      3 using namespace std;
      4 int r,c,i,j;//行 列
      5 char a[20][20]; //字符串的保存
      6 int used[20][20];//路径开头的标记
      7 int ans[100];//保存最大的路径
      8 int ansl;//保存最大路径的长度   
      9 int aa[100];//记录当前查找时候的路径
     10 int zhan[100][2];// 就是一个栈  用来求这一个点可以往后面走多远 
     11 int used1[20][20];// 还是路径的记录
     12 int neigh[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//可以走的4个方向
     13 int z;//表示当前查找的路径是否比已经记录的最大路径前缀大
     14 void search(int x,int y,int l)//搜索  x,y代表当前所在的位置   l代表当前路劲的长度
     15 {
     16     int i,j,top,bottom,xx,yy;
     17     if ((l>ansl)||((l==ansl)&&(z==1)))//位数比以前的大或者 位数一样 但是数值大的时候  更新ans数组  和ansl的值
     18     {
     19         memcpy(ans,aa,sizeof(ans));
     20         ansl=l;
     21         z=0;
     22     }
     23     memset(used1,0,sizeof(used1));
     24     used1[x][y]=1;
     25     top=0;bottom=1;
     26     zhan[0][0]=x;
     27     zhan[0][1]=y;
     28     while (top<bottom)//从当前的位置  后面还能走多少步
     29     {
     30         for (i=0;i<4;i++)
     31         {
     32             xx=zhan[top][0]+neigh[i][0];
     33             yy=zhan[top][1]+neigh[i][1];
     34             if ((xx>=0)&&(xx<r)&&(yy>=0)&&(yy<c)&&(a[xx][yy]!='#')&&(used[xx][yy]==0)&&(used1[xx][yy]==0))
     35             {
     36                 zhan[bottom][0]=xx;
     37                 zhan[bottom][1]=yy;
     38                 used1[xx][yy]=1;
     39                 bottom++;
     40             }
     41         }
     42         top++;
     43     }
     44     if (l+top-1<ansl) return;//如果当前长度+后继结点构成最长数长度<最大数长度 结束搜索
     45     if ((l+top-1==ansl)&&(z==-1)) return;//如果当前长度+后继结点构成最长数长度=最大数长度 但是比最长数小  同样结束搜索
     46     for (i=0;i<4;i++)
     47     {
     48         xx=x+neigh[i][0];
     49         yy=y+neigh[i][1];
     50         if ((xx>=0)&&(xx<r)&&(yy>=0)&&(yy<c)&&(a[xx][yy]!='#')&&(used[xx][yy]==0))
     51         {
     52             aa[l]=a[xx][yy]-'0';
     53             used[xx][yy]=1;
     54             if (z!=0)
     55                 search(xx,yy,l+1);//前面的数值已经比较出大小的  后面的数值不会对大小的比较产生影响
     56             else
     57                 if (l>=ansl)   
     58                 {
     59                     z=1;
     60                     search(xx,yy,l+1);
     61                     z=0;
     62                 }
     63                 else
     64                 {
     65                     if (aa[l]>ans[l])
     66                     {
     67                         z=1;
     68                         search(xx,yy,l+1);
     69                         z=0;
     70                     }
     71                     else if (aa[l]==ans[l])
     72                     {
     73                         z=0;
     74                         search(xx,yy,l+1);
     75                         z=0;
     76                     }
     77                     else
     78                     {
     79                         z=-1;
     80                         search(xx,yy,l+1);
     81                         z=0;
     82                     }
     83                 }
     84             used[xx][yy]=0;
     85         }
     86     }
     87 }
     88 
     89 int main()
     90 {
     91  92     while (~scanf("%d%d",&r,&c)&&c&&r)
     93     {
     94         for (i=0;i<r;i++)
     95             scanf("%s",a[i]);
     96         memset(ans,0,sizeof(ans));
     97         ans[0]=-1;
     98         ansl=1;
     99         memset(aa,0,sizeof(aa));
    100         for (i=0;i<r;i++)
    101             for (j=0;j<c;j++)//遍历每一个不是#号的地方   因为这一些地方都可以作为出发点
    102                 if (a[i][j]!='#')
    103                 {
    104                     used[i][j]=1;  // 记录  路径的开始
    105                     aa[0]=a[i][j]-'0'; //aa是用来保存当前搜索的路径
    106                     if (a[i][j]-'0'>ans[0])//比较大小  z=1代表大  0代表一样  -1代表小
    107                     {
    108                         z=1;
    109                         search(i,j,1);//搜索
    110                     }
    111                     else if (a[i][j]-'0'==ans[0])
    112                     {
    113                         z=0;
    114                         search(i,j,1);
    115                     }
    116                     else
    117                     {
    118                         z=-1;
    119                         search(i,j,1);
    120                     }
    121                     used[i][j]=0;
    122                 }
    123         for (i=0;i<ansl;i++)
    124             printf("%d",ans[i]);
    125         printf("
    ");
    126     }
    127     return 0;
    128 }
  • 相关阅读:
    php 制表符(\t) 与单引号的疑惑。
    preg_replace 正则替换的疑惑
    命令行下使用curl,采集数据遇到的问题。
    vmware player 里的window xp 安装wamp遇到的问题
    2014年11月05日
    2014年11月05日
    让开发人员搞业务是不对的
    2014年11月05日
    web应用.表格很重要
    业务复杂
  • 原文地址:https://www.cnblogs.com/52why/p/5840979.html
Copyright © 2011-2022 走看看