第七章习题G题

题意

给出如图案例,要你从某一点开始走,一直走到极限(即无法再进行扩展),这时你走过的点会连成一个数,不同的走法当然会有不同的数,要求是输出最大的数(注意每个方块走过一次就不能再走)

思路

•1.枚举所有的点作为起点,然后求从这个点所能得到的最大数

•2.然后是使用DFS求从某一点可以到达的最大数

可是仅仅使用DFS是会超时的,

所以,需要优化剪枝

Dfs的过程就是构建和遍历解答树的过程,在进行深度优先搜索时有一些分叉是可以判断出无需遍历的,这时就可以把这一部分跳过,continue掉

剪枝: 首先一个数它与另一个数最大的区别在于长度,即使它是最大的二位数,我是最小的三位数,我依然大于它,因此可以使用BFS,使用它去判断从这一点所能到达的最大长度,如果这个长度小于我之前所保留的最大长度,那么就不用再搜了,直接跳过。

还有一种情况,就是BFS出来的数长度和之前所保留的最大数长度相等呢?既然已经使用BFS做搜索预判,那么就不如在记录好从那一点所到达的最长距离所形成的数记录下来。然后比较这个数和保留的最大数,如果它小,那就甭走这走一步了

#include"iostream"
#include"cstring"
#include"queue"
#include"ctype.h"
#include"algorithm"
using namespace std;

char a[33][33];
int can[33];
int book[33][33];
int book2[33][33];
int m,n;
int nex[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
int tx,ty;

bool cmp(int a,int b)
{
return a>b;
}

typedef struct Node
{
    int no[33], len;
    void Init() {
        len = 0;
    }
    bool operator < (const Node &rhs) const {
        if(len != rhs.len) return len < rhs.len;
        for(int i = 0; i < len; ++i)
            if(no[i] != rhs.no[i]) return no[i] < rhs.no[i];
        return false;
    }
}Node;

Node ans,now;

int bfs(int x,int y)
{
queue<int> que; que.push(x *33 + y);
    int f = 1;
    can[0] = a[x][y] - ‘0‘;
    memset(book2, 0, sizeof(book2));
    book2[x][y] = 1;
    while(!que.empty()) {
        int tmp = que.front(); que.pop();
        int nx = tmp /33, ny = tmp % 33;
        for(int i = 0; i < 4; ++i) {
            int px = nx + nex[i][0], py = ny + nex[i][1];
            if(!isdigit(a[px][py]) || book[px][py] || book2[px][py]) continue;
            book2[px][py] = 1;
            can[f++] = a[px][py] - ‘0‘;
            que.push(px * 33+ py);
        }
    }
    return f;
 }

void dfs(int x,int y)
{
 now.no[now.len++] = a[x][y] - ‘0‘;
    book[x][y] = 1;
    for(int i = 0; i < 4; ++i) {
        int px = x +nex[i][0], py = y + nex[i][1];
        if(!isdigit(a[px][py]) || book[px][py]) continue;
        int wantlen = bfs(px, py);
        if(now.len + wantlen < ans.len) continue;
        if(now.len + wantlen == ans.len) {
            sort(can, can + wantlen);
            Node tmp = now;
            for(int i = wantlen - 1; i >= 0; --i) tmp.no[tmp.len++] = can[i];
            if(tmp < ans) continue;
        }
        dfs(px, py);
    }
    if(ans < now) ans = now;
    --now.len;
   book[x][y] = false;
}

int main()
{
while(cin>>m>>n&&m)
{
memset(a,0,sizeof(a));
memset(book,0,sizeof(book));
for(int i=0;i<m;i++) scanf("%s",a[i]);
ans.Init();now.Init();
for(int j=0;j<m;j++)
for(int k=0;k<n;k++)
if(isdigit(a[j][k])) dfs(j,k);

for(int kk=0;kk<ans.len;kk++) cout<<ans.no[kk];cout<<endl;
}
return 0;
}
时间: 2024-10-04 18:45:11

第七章习题G题的相关文章

Learning Perl 第九章习题第二题

把输入文件中的所有Fred换成Larry, 不区分大小写. 知识点 1. 文本文件读写 2. 简单的正则替换 3. unless 的用法 4. $_ 的用法 Learning Perl 第九章习题第二题,布布扣,bubuko.com

C和指针第七章第五题

实现一个简化的printf函数,能够处理%d,%f,%s,%c等格式. /************************************************************************* > File Name: permutation.c > Created Time: 2014年06月17日 星期二 23时22分34秒 *********************************************************************

鸟哥Linux私房菜第七章习题难题解答

1.找出/etc下面,文件大小介于50KB到60KB之间的文件,并且将权限完整的列出 答案为 find /etc -size +50k -size -60k -exec ls -l {} \; 或写成find /etc \( -size +50k -and -size -60k \) -exec ls -l {} \;也可以 2.找出/etc下面,文件容量大于50KB且文件所有者不是root的文件名,且将权限完整列出 答案为 find /etc -size +50k  ! -user root

corepython第七章习题

7-8.人力资源.创建一个简单的雇员姓名和编号的程序,让用户输入一组雇员姓名和编号.你的程序可以提供按照姓名排序输出的功能,雇员姓名显示在前面,后面是对应的雇员编号.附加题:添加一项功能,按照雇员编号的顺序输出数据. #coding:utf-8 def hr(): ep={} #生成字典 while True: ep_name=raw_input('please input employer name/n"q" for quit:') if ep_name=='q': break ep

概率论与数理统计严继高版第七章习题答案(含过程)

无7.3(不考)总习题我只有草稿,忘记带了,想起来就更 原文地址:https://www.cnblogs.com/cs-learn/p/9611237.html

Objective-C 程序设计(第六版)第七章习题答案

1.各个方法的实现 1 - (Fraction *) subtract: (Fraction *) f 2 { 3 Fraction *result = [[Fraction alloc] init]; 4 5 result.numerator = numerator *f.denominator - denominator *f.numerator; 6 result.denominator = denominator *f.denominator; 7 8 [result reduce];

C和指针 第七章 习题

7.1 hermite递归函数 int hermite(int n, int x) { if (n <= 0) { return 1; } if (n == 1) { return 2 * x; } return 2 * x * hermite(n - 1, x) - 2 * (n - 1) * hermite(n - 2, x); } 7.2两个整型值M和N(m.n均大于0)的最大公约数计算公式: gcd(M,N) 当M % N = 0;  N 当M % N =R, R > 0; gcd(N

python 核心编程 第七章习题

7-9. 翻译(a) 编写一个字符翻译程序(功能类似于Unix 中的tr 命令).我们将这个函数叫做tr(),它有三个字符串做参数: 源字符串.目的字符串.基本字符串,语法定义如下:def tr(srcstr, dststr, string)srcstr 的内容是你打算"翻译"的字符集合,dsrstr 是翻译后得到的字符集合,而string 是你打算进行翻译操作的字符串.举例来说,如果srcstr == 'abc', dststr == 'mno', string =='abcdef'

《Python核心编程》 第七章 映射和集合类型 - 习题

课后习题 7–1. 字典方法.哪个字典方法可以用来把两个字典合并到一起? 答: dict1 = {'1' :' python' } dict2 = {'2' :"hello" } dict1.update(dict2) dictAll = dict1 print dictAll Result: {'1': ' python', '2': 'hello'} 7–2. 字典的键.我们知道字典的值可以是任意的 Python 对象,那字典的键又如何呢?请试 着将除数字和字符串以外的其他不同类型