百练 2803:碎纸机

news/2024/11/23 9:53:19/

2803:碎纸机

http:、、bailian.openjudge.cn/practice/2803/

总时间限制: 
1000ms 
内存限制: 
65536kB
描述
你现在负责设计一种新式的碎纸机。一般的碎纸机会把纸切成小片,变得难以阅读。而你设计的新式的碎纸机有以下的特点:

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
解题思路:
因为最多只有6位数,所以可以一个一个的测试,暴力法!!
最开始先判断一下能不能得到结果,输入的数有多少位,就分解为多少个一位数,这样加起来的结果一定是所有结果中最小的,如果这个最小的结果都大于了你的目标的结果,那么就只有输出“error”,否则的话就可以开始递归寻找最接近目标的结果。
用一个bool型的变量来表示是不是有相同的最优的结果,如果最优的结果有两个或者两个以上,就会将flag置为true,否则的话flag就会始终为false。
因为最后还要输出分好的每一个数,所以定义temp数组来表示每一层的结果,如果这一次得到的最终的结果比上一次的要好,那么就将temp数组复制到part数组里面,这样就可以最后输出。我开始的时候没有设这个temp数组,只在每次满足条件,调用下一层函数的时候,就将part的当前的数更新,这样的话,最后得到的part数组始终是最后一次递归的,这样的话就错了,所以我还是定义了temp数组来保存该次的每一部分的数是多少。
递归函数的主体的算法思路是这样的:从当前的下标开始,将该从下标以后的字符串开始分割,先剪下来一个,将剪下来的结果存入temp[递归的层数]中,然后判断temp[……]+result 是不是小于等于目标结果res的,如果满足条件的话就调用下一层函数,将剩下的字符串的开始的下标(p+i)作为参数传入,然后再减下来两个(如果满足条件的话),然后以剩下的字符串的开始的下标(p+i)作为第二个参数传如调用的函数里面………………,最后,当字符串被遍历到最后的时候,判断当前的result是否大于了目前已经存在的max(前面得到的结果,如果是第一次的话,这个max已经在主函数里面初始化为0了),但是在判断result是不是大于max之前,要先判断max是不是等于result的,如果是等于的话就得将flag置为true(因为如果在将max的值改变之后再判断的话,那么接下来的max就始终是等于result的,那么就会导致flag始终为true。 )。如果max小于了result,就将max的值更新,然后再将当前存入的temp数组复制到part数组里面。
递归函数大概就是这样的。当然还有其他的思路和写法比我这更好大笑
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int mymax = 0;
char a[7];
bool flag;
int res;
int part[6];
int temp[6];
int number;
void fun(int result, int p,int len,int num)//当前的结果,当前数组开始的下标,数组长度
{int i;if(p == len){if(mymax == result){flag = true;}if(mymax < result){number = num;mymax = result;flag = false;for(i = 0;i<number;i++){part[i] = temp[i];}}return;}int j,n = 1;for(i=1;i<=len-p;i++)//取长度为i的字符串{temp[num] = 0;for(j=p,n = 0;n < i;n++,j++)//计算值{temp[num] = temp[num]*10 + a[j] - '0';}if(temp[num] + result <= res){//part[num] = temp;//这句话不能放这儿fun(result + temp[num],p+i,len,num+1);}}
}
int main()
{int len;int i;int sum;while(scanf("%d%s",&res,a)){mymax = 0;sum = 0;if(res == 0 && strcmp(a,"0") == 0)break;len = strlen(a);for(i = 0;i<len;i++){sum = sum + a[i] - '0';}if(sum > res)//因为都分为个位数,然后加起来是最小的,所以如果这个最小的数都大于了需要的数的话,那么就是error{printf("error\n");}else//否则的话就是可以得到,所以就开始判断{fun(0,0,len,0);if(flag == false){printf("%d",mymax);for(i=0;i<number;i++){printf(" %d",part[i]);}printf("\n");}elseprintf("rejected\n");}//printf("%d %s\n",res,a);}return 0;
}


 

http://www.ppmy.cn/news/126684.html

相关文章

碎纸机!

#include<stdio.h> #include<stdlib.h> #include<math.h> #include<string.h> //每次分割&#xff0c;分割出的数要小于目标数&#xff0c; int target_num,insert_num; char c_tar[50];//把目标数变为字符串 int result_temp[50]; int result…

攻防世界-碎纸机11

目录 文章目录 前言 一、安装imagemagick 二、下载题目文件解压 三.执行命令拼接图片 四.扫描二维码 总结 前言 攻防世界misc里面的碎纸机11(好像是这个,网站维护进不去没办法截图了) 翻了好久没找到适合我这种渣渣的wp 脑子抽了,kali虚拟机重新装了一次montage flag*.png …

攻防世界碎纸机11

碎纸机11 题目描述&#xff1a;我们从碎纸机里抢救回来了某个关键图片资料&#xff0c;你能帮我们修复它吗&#xff1f; 题目环境&#xff1a;https://download.csdn.net/download/m0_59188912/87094757 打开文件&#xff0c;发现是让我们拼图。 可以用python脚本进行拼接。 脚…

碎纸机

一个纸条进入&#xff0c;被切成很多个&#xff0c;其实纸条上写有一串的数字&#xff0c;被整数个地切割。其中满足的要求如下 1、被切出的数加起来的和要小于等于且最接近指定的一个数。 2、当没有满足这样的数时会报错。 3、当有多于一个的一样的数满足以上条件。 #incl…

【专题5: 硬件设计】 之 【34.案例三:碎纸机,碎纸机原理分析】

希望本是无所谓有&#xff0c;无所谓无的&#xff0c;这正如脚下的路&#xff0c;其实地上本没有路&#xff0c;走的人多了&#xff0c;也便成了路原创不易&#xff0c;文章会持续更新文章会同步到作者个人公众号上&#xff0c;感谢扫码关注 所有文章总目录&#xff1a;【嵌入式…

得力计算机无法开机,得力碎纸机维修常见故障及解决办法分享

碎纸机中&#xff0c;得力品牌的我们也是没少见了&#xff0c;得力碎纸机近几年也是得到大家的认可。所有东西用久了都会出现故障&#xff0c;所以今天小编整理了得力碎纸机维修常见故障及解决办法&#xff0c;供大家参考~ 得力碎纸机维修常见故障及解决办法&#xff1a; 一、机…

【Python从入门到进阶】22、urllib库基本使用

接上篇《21、爬虫相关概念介绍》 上一篇我们介绍了爬虫的相关概念&#xff0c;本篇我们来介绍一下用Python实现爬虫的必备基础&#xff0c;urllib库的学习。 一、Python库的概念 我们今后的学习可能需要用到很多python库&#xff08;library&#xff09;&#xff0c;及引用其…

交叉编译成LoongArch(Makefile,CMake,AutoTool,Qt等方式)

在嵌入板卡中由于资源有限常常使用像busybox这样的轻量文件系统。由于这类轻量文件系统没有编译系统在里面&#xff0c;所以如果需要软件在板卡上运行&#xff0c;那么交叉编译是必不可少的。 如果对交叉编译(cross compile)这个概念不太清楚的话&#xff0c;可以参考以下的一…