一、题目大意
切数字,求和,与目标数字比较,要就尽可能接近目标数字且比目标数字小。
二、解题思路
深搜,如果数字长n,则可以切[0, n-1]刀。对每种枚举。
其中由于我们只在意切得位置而不在意切得顺序,因此我们使用一个标记start
(见代码)表示最后一刀在哪个数字后。
三、代码
#include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std;
int numbers[7], sum2num[1000000+5], ans_numbers[7], cut[7];
int n_num, n_ans, ans, n, flag;
string t;
void t2array(string t)
{
for(int i=0; i<t.length(); i++)
numbers[i] = t[i] - '0';
n_num = t.length();
}
int get_num(int s, int t)
{
int res = 0;
for(int i=s; i<=t; i++)
res = res * 10 + numbers[i];
return res;
}
void dfs(int start, int deep, int tot)
{
if(deep == tot)
{
int s,t,num,temp_num[7];
// ----按切得地方分离各数字 -----//
s = 0;
for(int i=0; i<tot; i++)
{
t = cut[i];
num = get_num(s, t);
temp_num[i] = num;
s = t + 1;
}
num = get_num(s, n_num-1);
temp_num[tot] = num;
// ----求分离后的数字和 ---------//
int sum = 0;
for(int i=0; i<tot+1; i++)
sum += temp_num[i];
// ----判断是否是更好的答案 -----//
if(sum <= n && sum >= ans)
{
ans = sum;
n_ans = tot+1;
sum2num[sum]++;
flag = 1;
for(int i=0; i<n_ans; i++)
ans_numbers[i] = temp_num[i];
}
return;
}
// 第i个数字后切,
for(int i=start+1; i<n_num-1; i++)
{
cut[deep] = i;
dfs(i, deep+1, tot);
}
}
int main()
{
while(cin >> n >> t)
{
if(n == 0)
break;
memset(sum2num, 0, sizeof(sum2num));
ans = 0;
flag = 0;
n_num = 0;
t2array(t);
for(int i=0; i<n_num; i++)
dfs(-1, 0, i);
if(!flag)
cout << "error" << endl;
else if(sum2num[ans] > 1)
cout << "rejected" << endl;
else
{
cout << ans;
for(int i=0; i<n_ans; i++)
cout << " " << ans_numbers[i];
cout << endl;
}
}
return 0;
}