本题传送门

本题知识点:深度优先搜索 + 回溯

本题题意很简单,就是有一条位数不超过6的数字纸条,问你怎么剪这纸条,使得得到的纸条的值的总和最接近目标值(总和不能超过目标值)。

比如第一个样例

50 12346

12346可以剪成

1 2 3 4 6(总和16);12 34 6(总和52)等,其中最接近且不大于目标值的就是剪成1 2 34 6,总和是43,所以输出

43 1 2 34 6;

如果怎么剪都是大于目标值则输出

error

如果剪法有多种情况则输出

rejected

比如111 33333就有多种不同样的剪法带来相同的总和。

需要注意的是,数据输入保证没有前置0,但中间0也是要算进一种情况的,

比如 6 1104这例子1 1 0 4 与 1 1 04就属于两种不同的情况,但他们的和相等,所以就输出rejected了

那应该怎么剪呢?

我这里的做法是利用dfs的思想,到某一位上就有剪与不剪这种情况。

比如12346这条纸条,当我指到1这个数字上时,我剪下来就是1 2346,不剪就仍是12346,等到指到2时,剪下来就是12 346,如果前面1也剪了话就是 1 2 346了......依次类推,就可以写出dfs的递归过程。

注意回溯/(详细可看代码)

数据不大

  1. // POJ 1416
  2. #include<iostream>
  3. #include<cstdio>
  4. #include<cstring>
  5. using namespace std;
  6. int tar, num, Len, ans, minn;
  7. bool ok, take;
  8. int in[102], Ans[102];
  9. int cnt_in, cnt_ans;
  10. void setLen(){ // Len 记录可以剪与不剪的长度
  11. Len = 0;
  12. int q = num;
  13. while(q){ Len++; q /= 10; }
  14. }
  15. void dfs(int r, int len, int tot){ // r:当前纸条 len:判定到第几个数上 tot:剪下后的总和
  16. if(len == Len){ // 判断到最后的数字
  17. tot += r; // 加上最后的r
  18. if(r != 0) // 如果不是 0 要入数组(下面对应)
  19. in[cnt_in++] = r;
  20. if(tot <= tar){ // 先要比目标值小
  21. if(tar-tot < minn){ // 然后找差值最小的
  22. ok = true;
  23. minn = tar - tot;
  24. ans = tot;
  25. for(int i = 0; i < cnt_in; i++) Ans[i] = in[i]; cnt_ans = cnt_in;
  26. take = false; // 更新后就有新的答案数组 take 也要改变
  27. // 数据更新
  28. }
  29. else if(tar - tot == minn) { // 如果是相同的差值 判断是否重复(如果数组元素是一样的则不算)
  30. bool equ = true;
  31. if(cnt_ans == cnt_in){
  32. for(int i = 0; i < cnt_in; i++){
  33. if(Ans[i] != in[i]) {
  34. equ = false;
  35. }
  36. }
  37. }
  38. else equ = false;
  39. if(!equ) take = true;
  40. }
  41. }
  42. if(r != 0)
  43. cnt_in--; // 同样也是回溯
  44. return ;
  45. }
  46. // 记录当前 r 的长度
  47. int q = r, now = 0;
  48. while(q){ now++; q /= 10; }
  49. int pla = len - (Len - now); // 应该往右几位截取数据(这个规则可以自己动手算一算)
  50. int zero = 1;
  51. for(int i = 0; i < Len - len - 1; i++) zero *= 10;
  52. // 该位切
  53. int cro = r / zero; // 被剪下来的数
  54. in[cnt_in++] = cro; // 放进数组里(顺序表思路)
  55. dfs(r % zero, len + 1, tot + cro);
  56. cnt_in--; // 回溯,丢掉
  57. // 该位不切
  58. if(len == Len - 1 && num % 10 == 0 && r == 0) in[cnt_in++] = r; // 特判:判断原字条最后一位是否为0,如果是要入数组(取决于最后判断时的判断条件)
  59. dfs(r, len + 1, tot);
  60. if(len == Len - 1 && num % 10 == 0 && r == 0)cnt_in--; // 对于特判的回溯
  61. }
  62. int main()
  63. {
  64. while(~scanf("%d %d", &tar, &num) && tar + num){
  65. // 初始化工作
  66. memset(in, 0, sizeof(in));
  67. memset(Ans, 0, sizeof(Ans));
  68. cnt_in = cnt_ans = 0;
  69. ok = take = false; // ok 记录有满足的条件 take 记录是否有重复的满足条件
  70. ans = 0;
  71. minn = 0x3f3f3f3f;
  72. setLen();
  73. // 跑程序只是有一个dfs()
  74. dfs(num, 0, 0);
  75. // 答案输出
  76. if(ok && !take) {
  77. printf("%d ", ans);
  78. for(int i = 0; i < cnt_ans; i++)
  79. printf("%d%c", Ans[i], i == cnt_ans - 1 ? '\n' : ' ');
  80. }
  81. else if(ok && take) printf("rejected\n");
  82. else if(!ok) printf("error\n");
  83. }
  84. return 0;
  85. }

【POJ1416】Shredding Company的更多相关文章

  1. 【CF125E】MST Company(凸优化,最小生成树)

    [CF125E]MST Company(凸优化,最小生成树) 题面 洛谷 CF 题解 第一眼看见就给人丽洁姐那道\(tree\)一样的感觉. 那么二分一个权值,加给所有有一个端点是\(1\)的边, 然 ...

  2. 【POJ 1416】Shredding Company

    题 题意 给你一个target number,和一个最多六位的数num,让你把数分段,使总和最接近但不大于target number. 如果只有一种方法就输出总和.分段,如果有多种方法,输出rejec ...

  3. POJ 1416 Shredding Company【dfs入门】

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

  4. POJ1416——Shredding Company(DFS)

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

  5. 【CodeForces】790 C. Bear and Company 动态规划

    [题目]C. Bear and Company [题意]给定大写字母字符串,交换相邻字符代价为1,求最小代价使得字符串不含"VK"子串.n<=75. [算法]动态规划 [题解 ...

  6. 【lightoj-1039】A Toy Company(BFS)

    The toy company "Babies Toys" has hired you to help develop educational toys. The current ...

  7. poj1416 Shredding Company

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

  8. 【codeforces 794C】Naming Company

    [题目链接]:http://codeforces.com/contest/794/problem/C [题意] 有n个位置; 两个人; 每个人都有n个字符组成的集合s1,s2(可以有重复元素); 然后 ...

  9. 【VK Cup 2015 - Finals D】Restructuring Company

    [题目链接]:http://codeforces.com/problemset/problem/566/D [题意] 给你n个人; 一开始每个人都隶属于一个部门; 之后给你q个操作; 3种操作类型; ...

随机推荐

  1. .NET Core 傻瓜式CSRedisCore缓存

    作者:依乐祝原本链接:https://www.cnblogs.com/yilezhu/p/9947905.html 需要安装Redis   => https://www.runoob.com/r ...

  2. Java自学-数字与字符串 MyStringBuffer

    自己开发一个Java StringBuffer 根据接口IStringBuffer ,自己做一个MyStringBuffer 步骤 1 : IStringBuffer接口 package charac ...

  3. maven下载,上传设置

    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3. ...

  4. 安装socketio出现module 'importlib._bootstrap' has no attribute 'SourceFileLoader' 错误

    安装socketio出现module 'importlib._bootstrap' has no attribute 'SourceFileLoader' 错误 执行: pip install --u ...

  5. 排序算法的c++实现——计数排序

    任何比较排序算法的时间复杂度的上限为O(NlogN), 不存在比o(nlgN)更少的比较排序算法.如果想要在时间复杂度上超过O(NlogN)的时间复杂度,肯定需要加入其它条件.计数排序就加入了限制条件 ...

  6. MyCat教程一:MyCat的简单介绍

    MyCat教程二:mysql主从复制实现 MyCat教程三:安装及配置介绍 MyCat教程四:实现读写分离 MyCat教程五:实现分库分表 MyCat教程六:全局序列号-全局主键的自增长 一.MyCa ...

  7. linux cgroups简介(上)

    Linux CGroups简介 1.CGroups是什么 与Linux namespace对比来看,Linux namespace用来限制进程的运行范围或者运行环境的可见性,比如:uts限制进程读取到 ...

  8. AWS 存储过程

    DELIMITER $$ USE `mysql`$$ DROP PROCEDURE IF EXISTS `rds_rotate_slow_log`$$ CREATE DEFINER=`rdsadmin ...

  9. chrome开发者工具--使用 Network 面板测量您的网站网络性能。

    转自:Tools for Web Developers   Network 面板记录页面上每个网络操作的相关信息,包括详细的耗时数据.HTTP 请求与响应标头和 Cookie,等等. TL;DR 使用 ...

  10. Flutter初探与环境搭建

    最近组里有个前端的同事在疯狂学习Flutter,本来上半年就一直想学它,但是..由于个人的原因还有其它的东东想学就一直把它给无限搁置了,为了跟上时代的潮流所以接一来还是下定决定好好将它学一下,毕境如今 ...