Number
首先考虑使两数乘积最大。
为便于描述,将两个数前均加上
经过这样的变化后,有几个显然的性质:两数均在
设
假设将两数中在高位且值较大的数字跟另一数中在低位且值较小的数字交换。
设两数分别为
则交换
交换
设
则变化量(修改后减去修改前)为:
其中:
因为
因此两数长度差至多为
由于相同的权对应的能填的位置只有两个,因此我们可以确定每个数字对应的权,因此两数的和就被固定下来了。
显然,两数和一定,差越小,积越大,因此我们要分配两组数使得两数差最小。
假设两数分别为
从高位开始分配,第一次两数分配到的数不同后,假设
接下来考虑如何让两数
做个卷积把两数乘起来,输出乘积和 不会吧不会吧不会真的有人 T2 写卷积吧。
100 分:由于给定的数每个数至少有一个,因此两数必有一数以
由于两数开头一定为
代码:
#include<stdio.h>
char s1[1000005],s2[1000005];int l1,l2;
void half(char *s,int len)
{
int i;
for(i=0;i<len;i++)
{
s[i]-='0';
if(s[i]&1) s[i+1]+=10;
s[i]>>=1;
s[i]+='0';
}
if(s[0]=='0') puts(s+1);
else puts(s);
}
void dble(char *s,int len)
{
int i;_Bool fl=0;
for(i=len-1;i>=0;i--)
{
s[i]-='0';
if(s[i]>4) s[i]<<=1,s[i]-=10,s[i]+=fl,fl=1;
else s[i]<<=1,s[i]+=fl,fl=0;
s[i]+='0';
}
if(fl) putchar('1');
puts(s);
}
int main()
{
int i,j,a[10];_Bool flag=0;
for(i=0;i<10;i++)
scanf("%d",&a[i]);
for(j=0,i=9;j<2;j++)
{
for(;j&&i>=0;i--)
if(a[i])
{
a[i]--;
s2[l2++]='0'+i;
break;
}
for(;i>=0;i--)
{
while(a[i])
{
a[i]--;
if(!flag) s1[l1++]='0'+i;
else s2[l2++]='0'+i;
flag=!flag;
}
if(flag&&!j) break;
}
}
if(s1[l1-1]=='0')
{
half(s1,l1);
dble(s2,l2);
}
else
{
half(s2,l2);
dble(s1,l1);
}
return 0;
}