题意:
S(n)为n的各个位的数字之和,给出a,b,求最小的n值(n为正整数),使得a*S(n)=b*S(2*n),没有的话输出0
思路:
首先,1-9的S(n)值和S(2*n)值如下:
n S(n) S(2*n) S(2*n)-S(n)
1 1 2 1
2 2 4 2
3 3 6 3
4 4 8 4
5 5 1 -4
6 6 3 -3
7 7 5 -2
8 8 7 -1
9 9 9 0
其次,可以发现S(2*n)的值为S(n的各个位的数字的2倍)的和,所以我们可以凑出n中1-9的数量,在观察上面的1-9的表可以发现,2,3,4,即为2*1,3*1,4*1,6,7,8,9即为5+1,5+1*2,5+1*3,5+1*4,所以只要求出1和5的数量,就可以知道n值,因为要n最小,所以要数的位数小,尽可能多的转成9,8,……,在按1,2,3……的顺序正序输出,就是n的值了;
·设1有x个,5有y个,则可得公式 a*(x+5*y)=b*(2*x+y),可得x/y=(b-5*a)/(a-2*b),特判一下b-5*a=0和a-2*b=0的情况,
而且要求最小的n,记得求出最简的比值
ac代码:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
int v[15];
int gcd(int x,int y){
return x?gcd(y%x,x):y;
}
int main()
{
int t;
cin>>t;
while(t--){
memset(v,0,sizeof(v));
int a,b;
cin>>a>>b;
int y=a-2*b,x=b-5*a;
if(!x){//特判b=5*a,此时5 10符合条件
cout<<5<<endl;
continue;
}
if(!y){//特判a=2*b,此时1 2符合条件
cout<<1<<endl;
continue;
}
if(1.0*x/y<0){//比值为负证明无解
cout<<0<<endl;
continue;
}
x=abs(x),y=abs(y);
int t=gcd(x,y);
x/=t,y/=t;//求x和y的最简比
for(int i=9,j=4;i>5;i--,j--){//转成尽可能少的数
v[i]=min(y,x/j);
y-=v[i];
x-=v[i]*j;
}
v[5]=y;
for(int j=4;j>0;j--){
v[j]=x/j;
x-=v[j]*j;
}
for(int i=1;i<10;i++){//n最小,所以最高位的数最小
for(int j=0;j<v[i];j++){
cout<<i;
}
}
cout<<endl;
}
return 0;
}