ZCMU—1758

1758: Biggest Number

Time Limit: 1 Sec  Memory Limit: 128 MB
[Submit][Status][Web Board]

Description

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

3 7##9784###123####45###0 0

Sample Output

791452384

HINT

 

 

 

 

 

题意:有一个R*C的矩阵,矩阵里有1~9的数字,#表示墙,从矩阵任意一点出发,只能向上下左右移动,格子不能重复到达,把走过路径里的数字按位连起来组成一个很大的数字,求最大的数字。

【分析】
题意非常明确,一开始想到的是,连起来的位数越长,就越大(后来发现这并没有什么大用...)因为有30个点,bfs会炸内存,所以选择dfs,但是显然这道30个点的路径搜索加上每次需要按位比较数组,超时是一定的所以需要优化。

我觉得一般的优化意义不大,对于这种大数据优化还是比较明显需要剪枝....

第一个剪枝,非常简单,就是如果当前长度加上剩下可到达的位置所有长度加起来都小于当前解的长度,那就可以剪掉。这是最简单的优化,也比较暴力...无所谓判断,用一个很简单的路径覆盖的搜索去搜剩下的长度,虽然需要一个搜索去搜长度,但是能够剪掉的时间远远大于这个搜索。

然而一个剪枝并不够。。还是TLE所以只能继续想第二个优化。

第二个剪枝是基于第一个剪枝,既然已经剪掉了长度小的情况,那么长度和当前解的长度相同的时候,是不是也可以剪掉一部分呢,显然是可以的。

在搜索剩下长度的时候,边搜边比较,如果长度一样,那么就判断剩下路径中第一个和当前解答案不一样的位置,是大于当前解还是小于当前解,小于当前解,那么就可以直接退出,可能表达的不是很清楚,举个例子

比如当前搜到的是

1234,剩下可以搜到485

当前解是1234567

那么,在判断的时候 第一个与解不一样的位置是第五位也就是4,答案中是5.那么这个时候,长度一样,第一个不同位置比ans小,那就可以直接剪掉了。

因为显然12344**一定比1234567小。不管后面能搜到什么答案。

当时写的时候想到了一个自认为很巧妙的方法....在正常搜索的时候就直接记录一下当前这个位置和答案的大小,也就是代码里的bs变量。

这时候第二个剪枝就会变的非常简单,只是在第一个剪枝的if判断里多了一个条件而已

 

【代码】

#include <stdio.h>
#include <cstring> 
using namespace std;
 
 
char a[20][20];
int used[20][20]={0};
int usedd[20][20]={0};
int ans[200]={0};
int nowans[200]={0};
int bs,anslen=0,l,r,maxlen;
int move[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
 
void find(int x,int y,int len)
{
    if ((len>anslen)||(len==anslen && bs==1))
    {
        for (int i=0;i<len;i++) ans[i]=nowans[i];
        anslen=len;
        bs=0;
    }
     
    memset(usedd,0,sizeof(usedd));
    int maxlen=0,tot=1;
    int search[200][2]={0};
    search[0][0]=x;search[0][1]=y;
    usedd[x][y]=1;
    while (maxlen<tot)
    {
        for (int i=0;i<4;i++)
        {
            int xx,yy;
            xx=search[maxlen][0]+move[i][0];
            yy=search[maxlen][1]+move[i][1];
            if ((xx>=0)&&(yy>=0)&&(xx<l)&&(yy<r)&&(a[xx][yy]!='#')&&(used[xx][yy]==0)&&(usedd[xx][yy]==0))
            {
                usedd[xx][yy]=1;
                search[tot][0]=xx;
                search[tot][1]=yy;
                tot++;
            }
        }
        maxlen++;
    }
     
    if ((len+maxlen-1<anslen)||((len+maxlen-1==anslen) &&(bs==-1))) return;
     
     
    int xx,yy;
    for (int i=0;i<4;i++)
    {
        xx=x+move[i][0];
        yy=y+move[i][1];
        if ((xx>=0)&&(xx<l)&&(yy>=0)&&(yy<r)&&(used[xx][yy]==0)&&(a[xx][yy]!='#'))
        {
            nowans[len]=a[xx][yy]-48;
            used[xx][yy]=1;
            if (bs!=0) 
            {
                find(xx,yy,len+1);
            }
            else
            {
                if (len>=anslen)
                {
                    bs=1;
                    find(xx,yy,len+1);
                    bs=0;
                }
                else
                {
                    if(nowans[len]>ans[len])
                    {
                        bs=1;
                        find(xx,yy,len+1);
                        bs=0;
                    }
                    else
                    if (nowans[len]==ans[len])
                    {
                        bs=0;
                        find(xx,yy,len+1);
                        bs=0;
                    }
                    else
                    {
                        bs=-1;
                        find(xx,yy,len+1);
                        bs=0;
                    }
                }
            }
            used[xx][yy]=0;
        }
    }   
}
 
 
int main()
{
    scanf("%d %d",&l,&r);
    while (l!=0 && r!=0)
    {
        memset(ans,0,sizeof(ans));
        memset(nowans,0,sizeof(nowans));
        memset(used,0,sizeof(used));
        int i,j;
        for (i=0;i<l;i++) scanf("%s",&a[i]);
        for (i=0;i<l;i++)
            for (j=0;j<r;j++)
                if (a[i][j]=='#') used[i][j]=1;
        anslen=1;ans[0]=-1;
        for (i=0;i<l;i++)
            for (j=0;j<r;j++)
            if (a[i][j]!='#')
            {
                nowans[0]=a[i][j]-48;
                used[i][j]=1;
                if (nowans[0]>ans[0])
                {
                    bs=1;
                    find(i,j,1);
                }
                else
                if (nowans[0]==ans[0])
                {
                    bs=0;
                    find(i,j,1);
                }
                else
                if (nowans[0]<ans[0])
                {
                    bs=-1;
                    find(i,j,1);
                }
                used[i][j]=0;
                 
            }
        for (i=0;i<anslen;i++) printf("%d",ans[i]);
        printf("\n");scanf("%d %d",&l,&r);
    }
    return 0;
}

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了小程序应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
### 回答1: zcmu 1093 简单计算器是一道编程题目,要求实现一个简单的计算器,能够进行加、减、乘、除四种基本运算。该题目主要考察编程基础能力和算法思维能力,需要熟练掌握基本的运算符和控制语句,能够设计合理的算法实现计算器功能。 ### 回答2: zcmu 1093 简单计算器是一种基于计算机技术的工具,用于进行基本算术运算,如加减乘除等。它能够简化我们在日常生活中的计算工作,提高计算效率,减少出错率。 使用zcmu 1093 简单计算器非常简单,只需输入需要计算的数字和符号,就能够得到计算结果。它可以进行多个数字之间的复杂运算,同时还支持小数、百分数、平方根等复杂运算。另外,zcmu 1093 简单计算器还可以存储中间计算结果,方便我们进行多步计算或调整计算过程。 除了日常的计算工作,zcmu 1093 简单计算器还可用于科学计算、工程设计等领域。许多专业软件都是基于简单计算器原理设计的,它们具有更高的计算精度和更复杂的运算能力,能够支持更高级别的科学计算和技术分析。 总之,zcmu 1093 简单计算器在日常生活中有着广泛的应用,它使我们的计算工作变得更加高效、准确。并且,随着科技的不断发展,这种计算工具也在不断地更新和改进,为我们的计算工作提供更加便捷、多样化的选择。 ### 回答3: ZCMU 1093 简单计算器是一道基础的算法题目,需要实现一个简单的计算器程序,支持加、减、乘、除四种基本运算,可以对两个整数进行运算并输出结果。 要实现这道题目,首先需要根据输入的运算符来判断应该进行的运算类型,并根据运算符的不同,执行不同的计算操作。同时,应注意除数不能为零的情况,避免程序出现异常。 在编写程序的过程中,可以使用 switch case 语句来判断不同的运算类型,并执行相应的计算操作。同时,为了能有效地判断输入的运算符,可以使用输入字符串的方式进行处理,提取出运算符进行比较。 此外,在程序中还需要进行合法性判断,确保输入的数字均为整数且在合理的范围内,以避免程序运行出现异常情况。同时,还需要考虑输入格式的问题,应确保输入的数字和运算符符合题目要求。 综上所述,ZCMU 1093 简单计算器是一道基础的算法题目,需要实现一个简单的计算器程序,支持加、减、乘、除四种基本运算,注意程序的合法性判断和输入格式的处理,能够熟练地运用 switch case 等语句完成程序的编写。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值