碎纸机,详细注释
Posted lxzbky
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了碎纸机,详细注释相关的知识,希望对你有一定的参考价值。
你现在负责设计一种新式的碎纸机。一般的碎纸机会把纸切成小片,变得难以阅读。而你设计的新式的碎纸机有以下的特点: 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,在这种情况下,打印机会显示拒绝服务信息。 为了设计这样的一个碎纸机,你需要先写一个简单的程序模拟这个打印机的工作。给定两个数,第一个是目标数,第二个是输入纸片上的数,你需要给出碎纸机对纸片的分割方式。
Input
The input consists of several test cases, each on one line, as follows:
t1 num1
t2 num2
. . .
tn numn
0 0
Each test case consists of the following two positive integers, which are separated by one space: (1) the first integer (ti above) is the target number; (2) the second integer (numi above) is the number that is on the paper to be shredded.
Neither integers may have a 0 as the first digit, e.g., 123 is allowed but 0123 is not. You may assume that bother integers are at most 6 digits in length. A line consisting of two zeros signals the end of the input.
Output
For each test case in the input, the corresponding output takes one of the following three types:
- sum part1 part2 . . .
- rejected
- error
In the first type, partj and sum have the following meaning:
- Each partj is a number on one piece of shredded paper. The order of partj corresponds to the order of the original digits on the sheet of paper.
- sum is the sum of the numbers after being shredded, i.e., sum = part1 + part2 + . . .
Each number should be separated by one space.
The message error is printed if it is not possible to make any combination, and rejected if there is more than one possible combination.
No extra characters including spaces are allowed at the beginning of each line, nor at the end of each line.
Sample Input
50 12346
376 144139
927438 927438
18 3312
9 3142
25 1299
111 33333
103 862150
6 1104
0 0
Sample Output
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
思路:对于输入的字符串,依次先取长度1,2,3.....一直到串的最大长度
将取下的字符串处理,计算和
递归处理剩下的子串
递归结束,ans数组就是答案
#include<iostream>
#include<sstream>
#include<string>
#include<string.h>
#include<cstdio>
using namespace std;
int target,n;
int solutions[7];//分割的数字数组结果
int ans[7];//最大的分割数组结果
int counts=0,counta=0;//上面两个数组的长度
int Maxx = 0;
int MaxCount=0;//记录最大值可以组成的次数
void DFS(string text, int sum)
{
if (text.empty())//没有可以分割的字符了
{
if (sum > Maxx)
{
Maxx = sum;
MaxCount=1;//新的Maxx出现了一次,置为1,而不是++
counta = counts;//将分割的数字数组更新一下
for (int i = 0; i < counta; i++)
ans[i] = solutions[i];
}
else if (sum == Maxx)
{
MaxCount++;
}
return;
}
int temp;
stringstream stm;
for (int i = 1; i <=text.size(); i++)//这里text可能只有1个字符
{
stm.clear();stm.str("");
string textnext = text.substr(i);//从i往后,作为下一个分割目标
stm << text.substr(0,i);//截取前面i个字符
stm >> temp;
if (sum + temp > target)//和超过了限制
return;
solutions[counts++]=temp;//固定当前状态,分割的第一个数字记录下来
DFS(textnext,sum+temp);//在当前分割状态下,分割后面的字符串
solutions[--counts] = -1;//还原,准备下一次循环
}
}
int main() {
string text;
while (cin >> target >> text)
{
if (target == 0)
break;
n = text.size();
int temp = 0;
sscanf(text.c_str(), "%d", &temp);
if (temp == target)//相同,不用分割
{
cout << target << " ";
cout << target<<endl;
}
else {
DFS(text, 0);
if (MaxCount == 1)
{
cout << Maxx << " ";
for (int i = 0; i < counta - 1; i++)
{
cout << ans[i] << " ";
}
cout << ans[counta - 1]<<endl;
}
else if (MaxCount > 1)
{
cout << "rejected"<<endl;
}
else
cout << "error"<<endl;
}
counta = 0;
counts = 0;
MaxCount = 0;
Maxx = 0;
}
return 0;
}
以上是关于碎纸机,详细注释的主要内容,如果未能解决你的问题,请参考以下文章
高并发 WEB 服务器 nginx 源码通读中文分析注释,带详细函数注释及函数调用注释,附 github 地址,后期持续维护更新