热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

搜索+剪枝POJ1416ShreddingCompany

POJ1416ShreddingCompanyTimeLimit: 1000MSMemoryLimit: 10000KTotalSubmissions: 5231Accepted:

POJ 1416 Shredding Company
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 5231   Accepted: 2964

Description

You have just been put in charge of developing a new shredder for the Shredding Company Although a "normal" shredder would just shred sheets of paper into little pieces so that the contents would become unreadable, this new shredder needs to have the following unusual basic characteristics. 

1.The shredder takes as input a target number and a sheet of paper with a number written on it. 

2.It shreds (or cuts) the sheet into pieces each of which has one or more digits on it. 

3.The sum of the numbers written on each piece is the closest possible number to the target number, without going over it. 

For example, suppose that the target number is 50, and the sheet of paper has the number 12346. The shredder would cut the sheet into four pieces, where one piece has 1, another has 2, the third has 34, and the fourth has 6. This is because their sum 43 (= 1 + 2 + 34 + 6) is closest to the target number 50 of all possible combinations without going over 50. For example, a combination where the pieces are 1, 23, 4, and 6 is not valid, because the sum of this combination 34 (= 1 + 23 + 4 + 6) is less than the above combination‘s 43. The combination of 12, 34, and 6 is not valid either, because the sum 52 (= 12 + 34 + 6) is greater than the target number of 50. 
技术分享 
Figure 1. Shredding a sheet of paper having the number 12346 when the target number is 50


There are also three special rules : 

1.If the target number is the same as the number on the sheet of paper, then the paper is not cut. 

For example, if the target number is 100 and the number on the sheet of paper is also 100, then 

the paper is not cut. 

2.If it is not possible to make any combination whose sum is less than or equal to the target number, then error is printed on a display. For example, if the target number is 1 and the number on the sheet of paper is 123, it is not possible to make any valid combination, as the combination with the smallest possible sum is 1, 2, 3. The sum for this combination is 6, which is greater than the target number, and thus error is printed. 

3.If there is more than one possible combination where the sum is closest to the target number without going over it, then rejected is printed on a display. For example, if the target number is 15, and the number on the sheet of paper is 111, then there are two possible combinations with the highest possible sum of 12: (a) 1 and 11 and (b) 11 and 1; thus rejected is printed. In order to develop such a shredder, you have decided to first make a simple program that would simulate the above characteristics and rules. Given two numbers, where the first is the target number and the second is the number on the sheet of paper to be shredded, you need to figure out how the shredder should "cut up" the second number. 

Input

The input consists of several test cases, each on one line, as follows : 

tl 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 both 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 : 

1.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. 

2.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 /*这个题目比较难的地方就是记录是如何划分的,我这里用了一个path,path的位数表示划分成了几份,每一位path表示的是这一划分了几个*/
  2 #include
  3 #include
  4 #include
  5 using namespace std;
  6 #include
  7 #define N 10
  8 #include
  9 int tar;
 10 int visit[1000000],rel,path=0;
 11 char paper[N];
 12 int sum(const char *s)/*计算字符串表示的数*/
 13 {
 14     int len=strlen(s+1);
 15     int ans=0;
 16     for(int i=1;i<=len;++i)
 17       ans=ans*10+s[i]-0;
 18     return ans;
 19 }
 20 int get_ws(int n)/*取出n的位数,因为n顶多6位数*/
 21 {
 22     if(n<10) return 1;
 23     if(n<100) return 2;
 24     if(n<1000) return 3;
 25     if(n<10000) return 4;
 26     if(n<100000) return 5;
 27     return 6;
 28 }
 29 int get_pre(int n,int k)/*取出n的前k位*/
 30 {
 31     int ws=get_ws(n);
 32     return n/(int)pow(10.0,ws-k);/*这里pow中要用10.0,因为会有误差,比如pow(10,2)==99*/
 33 }
 34 void dfs(const char* s,int p,int sum1,int len)
 35 {
 36     if(sum1>tar) return;/*剪枝*/
 37     if(len==0)/*边界*//
 38     {
 39         visit[sum1]++;
 40         if(sum1>rel&&sum1<=tar)
 41         {
 42             path=p;
 43             rel=sum1;
 44         }
 45         return;
 46     }
 47     for(int i=1;i<=len;++i)
 48     {
 49         char a[10]={0},b[10]={0};
 50         int j,t;
 51         for(j=1;j<=i;++j)
 52           a[j]=s[j];
 53         a[j+1]=\0;
 54         for(t=1;j<=len;++j,++t)
 55           b[t]=s[j];
 56         b[++t]=\0;
 57         int now=sum(a);/*把a分为一份,枚举a的长度,然后递归分b*/
 58         p=p*10+i;/*记录划分方式*/
 59         dfs(b,p,sum1+now,strlen(b+1));
 60         p/=10;/*回溯*/
 61     }
 62 }
 63 int main()
 64 {
 65     while(scanf("%d%s",&tar,paper+1)==2)
 66     {
 67         int now=sum(paper);
 68         if(tar==0&&now==0) break;
 69         if(tar==now)
 70         {
 71             printf("%d %d\n",tar,tar);
 72             continue;
 73         }
 74         int len=strlen(paper+1);
 75         int su=0;
 76         for(int i=1;i<=len;++i)
 77            su+=paper[i]-0;
 78         if(su>tar)/*如果最小的划分方式都大于tar,那说明是达不到的*/
 79         {
 80             printf("error\n");
 81             continue;
 82         }
 83         dfs(paper,0,0,len);
 84         if(visit[rel]>1)/*到达超过一次,最好用数组统计,不会错,而且空间够*/
 85         {
 86             printf("rejected\n");
 87         }
 88         else{
 89             printf("%d ",rel);
 90             int i=1;
 91             while(path)/*输出划分方式*/
 92             {
 93                 int l=get_pre(path,1);
 94                 int k=l+i-1;
 95                 for(;i<=k;++i)
 96                   printf("%d",paper[i]-0);
 97                   printf(" ");
 98                 int ws=get_ws(path);
 99                 path-=l*(int)pow(10.0,ws-1);
100             }
101             printf("\n");
102         }
103         rel=0;path=0;tar=0;
104         memset(paper,0,sizeof(paper));
105         memset(visit,0,sizeof(visit));
106     /*别忘记初始化*/
107         }
108     return 0;
109 }

搜索+剪枝 POJ 1416 Shredding Company


推荐阅读
  • 本文探讨了如何在Classic ASP中实现与PHP的hash_hmac('SHA256', $message, pack('H*', $secret))函数等效的哈希生成方法。通过分析不同实现方式及其产生的差异,提供了一种使用Microsoft .NET Framework的解决方案。 ... [详细]
  • Python自动化测试入门:Selenium环境搭建
    本文详细介绍如何在Python环境中安装和配置Selenium,包括开发工具PyCharm的安装、Python环境的设置以及Selenium包的安装方法。此外,还提供了编写和运行第一个自动化测试脚本的步骤。 ... [详细]
  • 探讨 HDU 1536 题目,即 S-Nim 游戏的博弈策略。通过 SG 函数分析游戏胜负的关键,并介绍如何编程实现解决方案。 ... [详细]
  • 本文探讨了符号三角形问题,该问题涉及由相同数量的“+”和“-”符号组成的三角形。通过递归回溯法,可以有效地搜索并计算符合条件的符号三角形的数量。 ... [详细]
  • 本文详细介绍了在不同操作系统中查找和设置网卡的方法,涵盖了Windows系统的具体步骤,并提供了关于网卡位置、无线网络设置及常见问题的解答。 ... [详细]
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • 在尝试使用C# Windows Forms客户端通过SignalR连接到ASP.NET服务器时,遇到了内部服务器错误(500)。本文将详细探讨问题的原因及解决方案。 ... [详细]
  • 如何使用Ping命令来测试网络连接?当网卡安装和有关参数配置完成后,可以使用ping命令来测试一下网络是否连接成功。以winXP为例1、打开XP下DOS窗口具体操作是点击“开始”菜 ... [详细]
  • 鼠标悬停出现提示信息怎么做
    概述–提示:指启示,提起注意或给予提醒和解释。在excel中会经常用到给某个格子增加提醒信息,比如金额提示输入数值或最大长度值等等。设置方式也有多种,简单的,仅为单元格插入批注就可 ... [详细]
  • 本文探讨了为何相同的HTTP请求在两台不同操作系统(Windows与Ubuntu)的机器上会分别返回200 OK和429 Too Many Requests的状态码。我们将分析代码、环境差异及可能的影响因素。 ... [详细]
  • yikesnews第11期:微软Office两个0day和一个提权0day
    点击阅读原文可点击链接根据法国大选被黑客干扰,发送了带漏洞的文档Trumps_Attack_on_Syria_English.docx而此漏洞与ESET&FireEy ... [详细]
  • 深入解析动态代理模式:23种设计模式之三
    在设计模式中,动态代理模式是应用最为广泛的一种代理模式。它允许我们在运行时动态创建代理对象,并在调用方法时进行增强处理。本文将详细介绍动态代理的实现机制及其应用场景。 ... [详细]
  • 深入理解ExtJS:从入门到精通
    本文详细介绍了ExtJS的功能及其在大型企业前端开发中的应用。通过实例和详细的文件结构解析,帮助初学者快速掌握ExtJS的核心概念,并提供实用技巧和最佳实践。 ... [详细]
  • 通常情况下,修改my.cnf配置文件后需要重启MySQL服务才能使新参数生效。然而,通过特定命令可以在不重启服务的情况下实现配置的即时更新。本文将详细介绍如何在线调整MySQL配置,并验证其有效性。 ... [详细]
  • 本文详细介绍了 Python 中的条件语句和循环结构。主要内容包括:1. 分支语句(if...elif...else);2. 循环语句(for, while 及嵌套循环);3. 控制循环的语句(break, continue, else)。通过具体示例,帮助读者更好地理解和应用这些语句。 ... [详细]
author-avatar
鍾情噯伱_616
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有