题意和思路:
给定一个目标值,和一个待拆分数值。
拆分的过程其实就是在各个数字中间有状态0 1
0:有隔板
1:无隔板
所以最长6位数。所有暴力枚举的话也就2^5=32的时间复杂度。肯定能过。
暴力枚举的过程其实就是一个满二叉的深度优先搜索。
思路其实很简单,一眼就可以想到,只是处理输出的结果比较恶心,不过还是1A,小学期结束的晚上百无聊赖地1A道题心情还是比较好的。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<cmath>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define Abs(a) ((a)>0?(a):(-(a)))
#define llong long long int
using namespace std;
const int N=10;
const int inf=(1<<30);
int n;
char str[N];
int len;
int ans;
bool split[N];
bool spt[N];
bool isexist;
void dfs(int sum,int level,int pre)
{
int now=0;
for(int i=pre;i<level;i++)
{
now*=10;
now+=(str[i]-'0');
}
if(level==len)
{
sum+=now;
if(sum<=n&&ans>=0)
{
if(sum>ans)
{
ans=sum;
isexist=false;
for(int i=0;i<len;i++)
split[i]=spt[i];
}
else if(sum==ans)
{
isexist=true;
}
}
return;
}
if(sum>n)//剪枝
return;
spt[level]=false;
dfs(sum,level+1,pre); //每个位置枚举插隔板或是不插,即01枚举。
spt[level]=true;
dfs(sum+now,level+1,level);
}
int main()
{
while(scanf("%d%s",&n,str),n||(str[0]!='0'))
{
ans=0;
len=strlen(str);
spt[0]=true;
dfs(0,1,0);
if(isexist)
{
printf("rejected\n");
}
else if(ans>0)
{
printf("%d",ans);
for(int i=0;i<len;i++)
{
if(split[i])
printf(" ");
printf("%c",str[i]);
}
printf("\n");
}
else
{
printf("error\n");
}
}
return 0;
}