1.链接地址:

http://poj.org/problem?id=1416

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

2.题目:

总时间限制:
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
来源
翻译自Japan 2002 Kanazawa的试题

3.思路:

dfs(深度优先搜索)+剪枝

4.代码:

 #include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib> using namespace std; int max_sum; int res_sum;
vector<int> res_path;
int count; int sum;
vector<int> path; void dfs(string str)
{
//for(int v_i = 0; v_i < path.size(); ++v_i) cout << path[v_i] << " "; cout << "(" << str << ")(" << sum << ")";cout << endl;
if(str.size() == )
{ if(sum <= max_sum && sum == res_sum)
{
++count;
//res_path.clear();
//for(int v_i = 0; v_i < path.size(); ++v_i) res_path.push_back(path[v_i]);
//for(int v_i = 0; v_i < path.size(); ++v_i) cout << path[v_i] << " "; cout << "(" << str << ")(" << sum << ")";cout << endl;
res_path = path;
}
else if(sum <= max_sum && sum > res_sum)
{
res_sum = sum;
count = ;
//for(int v_i = 0; v_i < path.size(); ++v_i) cout << path[v_i] << " "; cout << "(" << str << ")(" << sum << ")";cout << endl;
res_path = path;
//res_path.clear();
//for(int v_i = 0; v_i < path.size(); ++v_i) res_path.push_back(path[v_i]);
}
return;
} for(int i = str.size() - ; i >= ; --i)
{
string str_left = str.substr(,i);
string str_right = str.substr(i); int left = atoi(str_left.c_str());
int right = atoi(str_right.c_str()); //剪枝
if(sum + right > max_sum) continue; //剪枝二
if(res_sum == max_sum && count > ) break; sum += right;
path.push_back(right); dfs(str_left); sum -= right;
path.pop_back();
} return;
} int main()
{
//freopen("C://input.txt","r",stdin); string str;
cin >> max_sum >> str; while(max_sum != || str.size() != || str[] != '')
{
int num = atoi(str.c_str());
if(num <= max_sum)
{
cout << num << " " << num << endl;
}
else
{
sum = ;
path.clear(); res_sum = -; dfs(str); if(res_sum == -) cout << "error" << endl;
else if(count > ) cout << "rejected" << endl;
else
{
cout << res_sum;
for(int i = res_path.size() - ; i >= ; --i) cout << " " << res_path[i];
cout << endl;
}
} cin >> max_sum >> str;
} return ;
}

OpenJudge 2803 碎纸机 / Poj 1416 Shredding Company的更多相关文章

  1. 搜索+剪枝 POJ 1416 Shredding Company

    POJ 1416 Shredding Company Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5231   Accep ...

  2. POJ 1416 Shredding Company【dfs入门】

    题目传送门:http://poj.org/problem?id=1416 Shredding Company Time Limit: 1000MS   Memory Limit: 10000K Tot ...

  3. POJ 1416 Shredding Company 回溯搜索 DFS

    Shredding Company Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6173   Accepted: 3361 ...

  4. poj 1416 Shredding Company( dfs )

    我的dfs真的好虚啊……,又是看的别人的博客做的 题目== 题目:http://poj.org/problem?id=1416 题意:给你两个数n,m;n表示最大数,m则是需要切割的数. 切割m,使得 ...

  5. POJ 1416 Shredding Company

    题目: http://poj.org/problem?id=1416 又16ms 1A了,这人品... #include <stdio.h> #include <string.h&g ...

  6. POJ 1416:Shredding Company

    Shredding Company Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4713   Accepted: 2714 ...

  7. POJ1416——Shredding Company(DFS)

    Shredding Company DescriptionYou have just been put in charge of developing a new shredder for the S ...

  8. poj1416 Shredding Company

    Shredding Company Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5379   Accepted: 3023 ...

  9. Shredding Company

    Shredding Company Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 4653 Accepted: 2675 Des ...

随机推荐

  1. datagridview控件--导出Excel

    dataGridView控件可以说很方便的显示了数据,而且对于修改和删除数据也很方便,我在前面的一篇博客中写到了如何去绑定数据到该控件上dataGridView控件--绑定数据方法,今天我将如何将数据 ...

  2. Java算法试题--猜字母/杀人游戏

    题目例如以下: 把abcd-s共19个字母组成的序列反复拼接106次,得到长度为2014的串. 接下来删除第1个字母(即开头的字母a).以及第3个,第5个等全部奇数位置的字母. 得到的新串再进行删除奇 ...

  3. Python 对新浪微博的博文元素 (Word, Screen Name)的频率分析

    CODE: #!/usr/bin/python # -*- coding: utf-8 -*- ''' Created on 2014-7-9 @author: guaguastd @name: we ...

  4. [AngularJS] Introduction to angular-formly

    <!DOCTYPE html> <html> <head> <!-- Each of these scripts are the latest version ...

  5. IOS - UIImage

    IOS中对图片的处理 UIImage UIImage 继承于NSObject 以下介绍一下UIImage中的方法 首先是我们最经常使用的 通过图片的文件名称来获取这个图片 + (UIImage *)i ...

  6. Python 魔术方法指南

    入门 构造和初始化 构造定制类 用于比较的魔术方法 用于数值处理的魔术方法 表现你的类 控制属性访问 创建定制序列 反射 可以调用的对象 会话管理器 创建描述器对象 持久化对象 总结 附录 介绍 此教 ...

  7. DebuggingWithGdb

    https://wiki.python.org/moin/DebuggingWithGdb http://blog.nsfocus.net/python-program-troubleshooting ...

  8. HttpWebRequest 模拟登录响应点击事件(分享自己用的HttpHelper类)

    平时也经常采集网站数据,也做模拟登录,但一般都是html控件POST到页面登录:还没有遇到用户服务器控件button按钮点击事件登录的,今天像往常一样POST传递参数,但怎么都能登录不了:最后发现还有 ...

  9. js之createTextRange方法

    createTextRange()方法作用: 主要是用来对一些文本对象进行操作.比如你有一大段文字,都在同一个P标签内,但是你只希望通过JS改变其中的一小部分,这时就可以用createTextRang ...

  10. linux 学习笔记 Linux内核的四大功能简介

    一 内存管理 默认情况下,运行在Linux系统上的每个进程都有各自的内存页面:进程不能访问其他进程正在使用的内存页面. 内核维护着自己的内存区域 用户进程不能访问内核进程的内存 可以创建一些共享内存页 ...