又是一道图文并茂的题。绝对绝对绝对比英语阅读理解长!
题目大意:
每组测试数据就是给你两个数,s,n;让你给第2个数n分成几个数,问你怎么分可以让这些分得的数的和在不超过 s的情况下最接近s。s,n最多六位。还有一些细节比如:输入的每个数开头都不为0,由样例:6 1104-->rejected可知,分成的数的开头可以为0;
对于一个n,枚举它所有的可能划分和有2^5=32种。关键就是他并没有说有多少组测试实例。直接枚举0ms过了。
猜想:这里对于一个6位数n,将它分成一个1位数和一个5位数求和显然是要大于将它分为一个2位数和一个四位 数求和的。(待证明)
题目大意:
每组测试数据就是给你两个数,s,n;让你给第2个数n分成几个数,问你怎么分可以让这些分得的数的和在不超过 s的情况下最接近s。s,n最多六位。还有一些细节比如:输入的每个数开头都不为0,由样例:6 1104-->rejected可知,分成的数的开头可以为0;
对于一个n,枚举它所有的可能划分和有2^5=32种。关键就是他并没有说有多少组测试实例。直接枚举0ms过了。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
using namespace std;
int s;
int a[10]={0};
bool move[10]={0};
int n;
int best;
bool only;
int step[10]={0};
int get_sum()
{
int sum=a[0];
int j=0;
int i=1;
while(1)
{
if(i>=n)break;
if(move[i])
{
j++;
}
else j=0;
sum=sum+pow(10.0,j)*a[i];
i++;
}
return sum;
}
void dfs(int x)
{
if(x==n)
{
int t=get_sum();
//cout<<t<<" ";
if(t==best)
{
only=0;
return;
}
if(t<=s&&t>best)
{
for(int i=0;i<n;i++)
{
step[i]=move[i];
}
best=t;
only=1;
return;
}
return;
}
for(int i=0;i<2;i++)//move[i]表示a[i]位后面是否需要划分
{
move[x]=i;
dfs(x+1);
}
}
void ceshi()
{
for(int i=0;i<n;i++)
{
cout<<a[i];
}
cout<<endl;
}
int main()
{
while(scanf("%d",&s))
{
int l;
n=0;
scanf("%d",&l);
if(s==0&&l==0)break;
while(1)//个位a[0],有n位
{
a[n]=l%10;
n++;
l/=10;
if(l==0)break;
}
best=-1;
only=1;
dfs(1);
if(best==-1)
{
printf("error\n");
continue;
}
if(only==0)
{
printf("rejected\n");
continue;
}
cout<<best<<" ";
for(int i=n-1;i>=0;i--)
{
cout<<a[i];
if(step[i]==0&&i!=0)cout<<" ";
}
cout<<endl;
}
}
猜想:这里对于一个6位数n,将它分成一个1位数和一个5位数求和显然是要大于将它分为一个2位数和一个四位 数求和的。(待证明)