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. multiselect获取选中的多个下拉项的值(逗号分割的字符串)

    /*传入下拉select标签*/ function get_selected(mslt_employees) { var emplo =mslt_employees.multiselect(" ...

  2. 【Android开发经验】使用Ant批量打包Android应用全然指南

    本文章由Socks完毕.博客地址:http://blog.csdn.net/zhaokaiqiang1992 转载请说明. 折腾了一下午.百度了一下午,最终实现了使用Ant对Android应用的批量打 ...

  3. [转]详述DHCP服务器的三种IP分配方式

    DHCP就是动态主机配置协议(Dynamic Host Configuration Protocol),它的目的就是为了减轻TCP/IP网络的规划.管理和维护的负担,解决IP地址空间缺乏问题.这种网络 ...

  4. js获取光标位置例子

    <html><head><title>TEST</title><style>body,td { font-family: verdana, ...

  5. java_Cookies_1_商品浏览历史记录servlet1

    public class CookiesServlet1 extends HttpServlet { public void doGet(HttpServletRequest request, Htt ...

  6. Android自定义标题TitleView

    Android开发过程中,经常遇到一个项目需要重复的定义相同样式的标题栏,Android相继推出了actionBar, toolBar, 相信有用到的朋友也会遇到一些不如意的时候,比如标题栏居中时,需 ...

  7. 常用CentOS 6/7 扩展源

    1.系统自带 baseextrasupdates 2.epel yum install epel-release https://fedoraproject.org/wiki/EPEL 3.el(用于 ...

  8. dos下循环复制一张图片的bat

    @echo off setlocal enabledelayedexpansion ,,) do ( @echo !dm! copy .png !dm!.png ) 我期待的结果是将140041.pn ...

  9. 通过样式调整input 中password text默认长度

    原文出处 <input >标签内的type分别为password和text时其默认长度和宽度不一致,而在做登陆框时往往需要将它们的长度和宽度设置一致.如下的方法可以通过css控制使其一致: ...

  10. js限制文本框只能输入数字

    JS判断只能是数字和小数点1.文本框只能输入数字代码(小数点也不能输入) <input onkeyup="this.value=this.value.replace(/\D/g,'') ...