HDU 5710 Digit-Sum

来源:互联网 发布:冒险岛怎么升级v矩阵 编辑:程序博客网 时间:2024/06/15 04:49

题目链接:点击打开链接

原博客链接:点击打开链接



5*2=10,S(5*2)=1,2*S(5)=10;
6*2=12,S(6*2)=3,2*S(6)=12;
7*2=14,S(7*2)=5,2*S(7)=14;
8*2=16,S(8*2)=7,2*S(8)=16;
9*2=18,S(9*2)=9,2*S(9)=18;

规律显然,其实就是满十进1,每位数字之和便小了9。


假设n里有L位数为5-9,那么显然满足:S(2n)=S(n)*2-L*9


那么a*S(n) == b*(2S(n)-L*9)
化简:(2b-a)*S(n) == 9*L*b

关键:9*b:2b-a = S(n):L


到此可以推出三个结论

if (L==0) {printf ("1\n"); continue;}   //L=0时,S(2)=2*S(1)
if (L<0) {printf ("0\n"); continue;}   //(2b-a)*S(n) == 9*L*b,L不可能小于0
if (5*L>S) {printf ("0\n"); continue;}   //假设就是5-9部分有L位,如果最小的5乘以L都会爆,那么不符合假设

我对这道题的理解是

S(n):L=9*b:2b-a只要写出来这个式子我就可以知道S(n)与L的关系。当然这两个数都没有公约数了。

比如3 4这组样例,那么算出来S(N)=36:L=5。那么也就是说吧36分在这一些数上,并且我们知道大于5的数有5个。那么我们先把这5个数都写成5,然后看S(n)=36-5*5=12在这些数上填充到9看最后会不会把S(n)用完,如果用完了那这个数就是我们要的数,如果没有那继续往前边填充。不过不同的是,前边的数不会超过4,同前边一样向前填充,直到把S(n)用完。这是个贪心的思想

这是我的粗略代码:

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int aa[500];int main(){    int t,a,b;    scanf("%d",&t);    while(t--)    {        memset(aa,0,sizeof(aa));        scanf("%d%d",&a,&b);        if(a==2*b)            printf("1\n");        else if(2*b<a)            printf("0\n");        else if(5*a<b)            printf("0\n");        else        {            int sum=9*b;            int l=2*b-a;            int x=__gcd(sum,l);            l/=x;            sum/=x;            int ans=sum-5*l;            for(int i=0; i<l; i++)            {                if(ans<4)                {                    aa[i]=5;                    aa[i]+=ans;                    ans-=ans;                }                else                {                    aa[i]=5;                    aa[i]+=4;                    ans-=4;                }            }            int xx=0;            if(ans)            {                for(int i=l;; i++)                {                    if(ans==0)                        break;                    if(ans<=4)                    {                        aa[i]+=ans;                        ans-=ans;                        xx++;                    }                    else                    {                        aa[i]+=4;                        ans-=4;                        xx++;                    }                }            }//            int j;//            for(int j=250;j>=0;j--)//                if(aa[j]) break;            for(int i=l-1+xx; i>=0; i--)                printf("%d",aa[i]);            printf("\n");        }    }}


原创粉丝点击