贤鱼刷题日常 1805.碎纸机

简介: 碎纸机详细题解

@TOC

题目描述

描述
你现在负责设计一种新式的碎纸机。一般的碎纸机会把纸切成小片,变得难以阅读。而你设计的新式的碎纸机有以下的特点:

1.每次切割之前,先要给定碎纸机一个目标数,而且在每张被送入碎纸机的纸片上也需要包含一个数。
2.碎纸机切出的每个纸片上都包括一个数。
3.要求切出的每个纸片上的数的和要不大于目标数而且与目标数最接近。

举一个例子,如下图,假设目标数是50,输入纸片上的数是12346。碎纸机会把纸片切成4块,分别包含1,2,34和6。这样这些数的和是43 (= 1 + 2 + 34 + 6),这是所有的分割方式中,不超过50,而又最接近50的分割方式。又比如,分割成1,23,4和6是不正确的,因为这样的总和是34 (= 1 + 23 + 4 + 6),比刚才得到的结果43小。分割成12,34和6也是不正确的,因为这时的总和是52 (= 12 + 34 + 6),超过了50。
在这里插入图片描述

还有三个特别的规则:
1.如果目标数和输入纸片上的数相同,那么纸片不进行切割。
2.如果不论怎样切割,分割得到的纸片上数的和都大于目标数,那么打印机显示错误信息。
3.如果有多种不同的切割方式可以得到相同的最优结果。那么打印机显示拒绝服务信息。比如,如果目标数是15,输入纸片上的数是111,那么有两种不同的方式可以得到最优解,分别是切割成1和11或者切割成11和1,在这种情况下,打印机会显示拒绝服务信息。

为了设计这样的一个碎纸机,你需要先写一个简单的程序模拟这个打印机的工作。给定两个数,第一个是目标数,第二个是输入纸片上的数,你需要给出碎纸机对纸片的分割方式。
输入
输入包括多组数据,每一组包括一行。每行上包括两个正整数,分别表示目标数和输入纸片上的数。已知输入保证:两个数都不会以0开头,而且两个数至多都只包含6个数字。

输入的最后一行包括两个0,这行表示输入的结束。
输出
对每一组输入数据,输出相应的输出。有三种不同的输出结果:

sum part1 part2 ...
rejected
error

第一种结果表示:
1.每一个partj是切割得到的纸片上的一个数。partj的顺序和输入纸片上原始数中数字出现的次序一致。
2.sum是切割得到的纸片上的数的和,也就是说:sum = part1 + part2 +...
第一种结果中相邻的两个数之间用一个空格隔开。

如果不论怎样切割,分割得到的纸片上数的和都大于目标数,那么打印“error”。
如果有多种不同的切割方式可以得到相同的最优结果,那么打印“rejected”。
样例输入
50 12346
376 144139
927438 927438
18 3312
9 3142
25 1299
111 33333
103 862150
6 1104
0 0
样例输出
43 1 2 34 6
283 144 139
927438 927438
18 3 3 12
error
21 1 2 9 9
rejected
103 86 2 15 0
rejected
这道题搜索看看在哪里切割符合题意即可

AC代码(放心食用)

#include<cmath>
#include<iostream>
#include<cstring>
#include<stdlib.h>
#include<cstdio>
using namespace std;
int v;
int cnt;
int n;
int s;
char a[404];
int maxx=0;
int a1[404],a2[404];
void dfs(int x,int y,int z){
    if(y>n){//如果答案已经大于目标,直接结束
        return ;
    }
    if(x>=s){//如果长度已经切完了,处理一下答案
        if(y==maxx){
            v++;
        }
        if(y>maxx){
            maxx=y;
            v=1;
            for(int i=1;i<z;i++){
                a2[i]=a1[i];
            }
            cnt=z-1;
            return;
        }
    }
    int tmp=0;
    for(int i=x;i<s;i++){//这里就是每一位都切一下试试
        tmp=tmp*10+a[i]-'0';//如果这位不切在下一次处理的时候大于答案了,那么从此往后都会在下一次处理结束程序,所以只有符合题意的才能继续往下处理
        a1[z]=tmp;
        dfs(i+1,y+tmp,z+1);//递归寻找答案
    }
}
int main(){
    while(1){
        v=0;
        maxx=0;
        cin>>n>>a;//方便处理
        s=strlen(a);
        if(n==0) break;//判断一下是否结束输入
        if(atoi(a)==n){
            cout<<n<<" "<<n<<endl;
            continue;
        }
        dfs(0,0,1);
        if(maxx==0){//从这里往下就是按照题目处理答案了
            cout<<"error"<<endl;
            continue;
        }
        if(v!=1){
            cout<<"rejected"<<endl;
            continue;
        }
        cout<<maxx<<" ";
        for(int i=1;i<=cnt;i++){
            cout<<a2[i]<<" ";
        }
        cout<<endl;

    }
}

@^ _ ^@

相关文章
|
算法 C++ Python
每日算法系列【LeetCode 825】适龄的朋友
每日算法系列【LeetCode 825】适龄的朋友
|
存储 移动开发 算法
leetcode刷题周记-2021.11.21-2021.11.28
leetcode刷题周记-2021.11.21-2021.11.28
95 0
leetcode刷题周记-2021.11.21-2021.11.28
|
机器学习/深度学习 存储 人工智能
leetcode刷题周记-2021.11.14~2021.11.20
leetcode刷题周记-2021.11.14~2021.11.20
123 0
leetcode刷题周记-2021.11.14~2021.11.20