题目链接:点击打开链接
大致题意:
公司现在要发明一种新的碎纸机,要求新的碎纸机能够把纸条上的数字切成最接近而不超过target值。比如,target的值是50,而纸条上的数字是12346,应该把数字切成四部分,分别是1、2、34、6。因为这样所得到的和43 (= 1 + 2 + 34 + 6) 是所有可能中最接近而不超过50的。(比如1, 23, 4, 和6 就不可以,因为它们的和不如43接近50,而12, 34, 6也不可以,因为它们的和超过50了。碎纸还有以下三个要求:
1、如果target的值等于纸条上的值,则不能切。 2、如果没有办法把纸条上的数字切成小于target,则输出error。如target是1而纸条上的数字是123,则无论你如何切得到的和都比1大。 3、如果有超过一种以上的切法得到最佳值,则输出rejected。如target为15,纸条上的数字是111,则有以下两种切法11、1或者1、11. 你的任务是编写程序对数字进行划分以达到最佳值。
思路:
这个题跟上一道题(2531)一样,用dfs暴力枚举就好了,一共需要2^6 = 64次 铁定不会超时。
代码:
#include <iostream> #include <string.h> #include <stdio.h> using namespace std; struct node { int sum; bool index[7]; }mx; int target; string date; bool vis[7]; int flag[1000000]; int len; void dfs(int x) { if(x == len) { vis[0] = true; int tmp = 0, t = 1; int sum = 0; for(int i = len-1;i >= 0;i--) { if(!vis[i]) tmp += (date[i] - '0')*t, t *= 10; else tmp += (date[i] - '0')*t, t=1, sum += tmp, tmp = 0; } if(sum >= mx.sum && sum <= target) { flag[sum]++; mx.sum = sum; for(int i = 0;i < 7;i++) mx.index[i] = vis[i]; } return; } vis[x] = true; dfs(x+1); vis[x] = false; dfs(x+1); } int main() { ios::sync_with_stdio(false); while(cin>>target>>date,target || date != "0") { memset(flag,0,sizeof(flag)); mx.sum = 0; len = date.length(); dfs(1); if(mx.sum == 0) cout<<"error"<<endl; else if(flag[ mx.sum ] > 1) cout<<"rejected"<<endl; else { cout<<mx.sum<<' '<<date[0]; for(int i = 1;i < len;i++) if(mx.index[i]) cout<<' '<<date[i]; else cout<<date[i]; cout<<endl; } } return 0; }
