【HDU5710】Digit-Sum-思维+构造

测试地址:Digit-Sum
题目大意:S(n)S(n)nn的十进制表示的各个数位之和,要求构造出一个最小正整数满足aS(n)=bS(2n)a\cdot S(n)=b\cdot S(2n)
做法: 本题需要用到思维+构造。
我们尝试找出从nn变成2n2n后,数位和的变化。令nn包含的5\ge 5的数位有xx个,那么变成2n2n后就会进xx次位,每进一次位,个位减1010,十位加11,所以S(2n)=2S(n)9xS(2n)=2S(n)-9x
于是我们就把题目中的式子改成:(2ba)S(n)=9bx(2b-a)S(n)=9b\cdot x。于是分类讨论:
2ba<02b-a<0,显然无解。
2ba=02b-a=0,那么11是最小的答案。
否则,先将2ba2b-a9b9b约分,剩下pS(n)=qxpS(n)=qx。有一个结论是,当x=p,S(n)=qx=p,S(n)=q时无解,则整个式子无解,否则当x=p,S(n)=qx=p,S(n)=q时得到的解最优。
首先x=p,S(n)=qx=p,S(n)=q无解,充要条件是5x>S(n)5x>S(n),当xx变为kpkp时,S(n)S(n)变为kqkq,而5kx>kS(n)5kx>kS(n),所以还是无解。
然后,如果x=p,S(n)=qx=p,S(n)=q时有解,一种构造的方法是,首先写出xx55,然后把S(n)S(n)中剩余的部分尽可能加在低位上,如果S(n)>9xS(n)>9x,那么就要把剩余的部分加在比xx位更高的那些位上,显然也是尽量加在低位上,而这些位所能填的上限都是44(因为定义了xx5\ge 5的数位数,不能影响)。这样就能构造出一个解了。
那么当x=kp,S(n)=kqx=kp,S(n)=kq,显然解不会更优,因为堆积的位数一定会更多。这样一来,我们就可以直接按照上面的方法构造了。
以下是本人代码:

#include <bits/stdc++.h>
using namespace std;
int T,a,b,digit[10010];

int gcd(int a,int b)
{
	return (b==0)?a:gcd(b,a%b);
}

int main()
{
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&a,&b);
		int x=2*b-a,s=9*b;
		if (x==0) {printf("1\n");continue;}
		if (x<0) {printf("0\n");continue;}
		
		int g=gcd(x,s);
		x/=g,s/=g;
		if (5*x>s) {printf("0\n");continue;}
		
		int tot=x;
		for(int i=1;i<=x;i++)
			digit[i]=5;
		s-=5*x;
		for(int i=1;i<=x;i++)
		{
			digit[i]+=min(4,s);
			s-=digit[i]-5;
			if (!s) break;
		}
		
		while(s)
		{
			digit[++tot]=min(4,s);
			s-=digit[tot];
		}
		
		for(int i=tot;i>=1;i--)
			printf("%d",digit[i]);
		printf("\n");
	}
	
	return 0;
}
posted @ 2018-09-20 22:27  Maxwei_wzj  阅读(200)  评论(0编辑  收藏  举报