“Forever number” is a positive integer A A A with K K K digits, satisfying the following constrains:
- the sum of all the digits of A A A is m m m;
- the sum of all the digits of A + 1 A+1 A+1 is n n n; and
- the greatest common divisor of m m m and n n n is a prime number which is greater than 2.
Now you are supposed to find these forever numbers.
Input Specification:
Each input file contains one test case. For each test case, the first line contains a positive integer N ( ≤ 5 ) N (≤5) N(≤5). Then N N N lines follow, each gives a pair of K ( 3 < K < 10 ) K (3<K<10) K(3<K<10) and m ( 1 < m < 90 ) m (1<m<90) m(1<m<90), of which the meanings are given in the problem description.
Output Specification:
For each pair of
K
K
K and
m
m
m, first print in a line Case X
, where X
is the case index (starts from 1). Then print
n
n
n and
A
A
A in the following line. The numbers must be separated by a space. If the solution is not unique, output in the ascending order of
n
n
n. If still not unique, output in the ascending order of
A
A
A. If there is no solution, output No Solution
.
Sample Input:
2
6 45
7 80
Sample Output:
Case 1
10 189999
10 279999
10 369999
10 459999
10 549999
10 639999
10 729999
10 819999
10 909999
Case 2
No Solution
这道题的大意是:给你两个数K和m,你要找出所有符合以下条件的K位数:首先,所有位数之和等于m,其次,这个数加一之后得到的新的数所有位数之和等于n,而且n、m的最大公约数是大于2的质数。
我这道题大概写了四十分钟才写完,说实话这样的题真的打击pat选手的心情啊,好在小题难,大题就简单,我就用了俩小时就做完了全部四道题(还是第一题最难)
这道题的思路是枚举k位数的每一位,并计算出对应的n,依次检测n和m的最大公约数是否符合条件。
观察到k大于3小于10,也就是说最大k是9。再分析一下题干,假设k=9,那么只需要枚举其中的8位,最后1位可以直接用m减去其余位数得到;继续分析,发现个位只能等于9。因为假设个位不等于9,那么这个数加一之后不会产生任何进位,那么n就等于m+1,m+1和m之间显然最大公约数只能是1,不符合条件。因此k=9的时候只需要枚举7个数位即可。
我的思路是分情况讨论k等于4,5,6,7,8,9的时候的做法。看起来有点麻烦,但其实复制粘贴就行。
#include <iostream>
#include<algorithm>
#include<cstdio>
#include<map>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;
int N,k,m;
int gcd(int x,int y)
{
return y>0?gcd(y,x%y):x;
}
int gcd1(int x,int y)
{
if(x<y)swap(x,y);
return gcd(x,y);
}
bool isPrime(int x)
{
if(x<=2)return false;
for(int i=2;i<=sqrt(x);i++)
{
if(x%i==0)return false;
}
return true;
}
struct Node
{
int n;
long long a;
};
vector<Node>v;
bool cmp(Node&x,Node&y)
{
if(x.n!=y.n)
return x.n<y.n;
else return x.a<y.a;
}
void compute(long long real)
{
long long n1=0;
long long real1=real;
while(real)
{
n1+=real%10;
real/=10;
}
int n=(int)n1;
int gcds=gcd1(m,n);
if(isPrime(gcds))
{
Node node;
node.n=n;
//cout<<"real-1:"<<real<<endl;
node.a=real1-1;
v.push_back(node);
}
}
int main()
{
scanf("%d",&N);
for(int nn=1;nn<=N;nn++)
{
v.clear();
scanf("%d%d",&k,&m);
int sum=9;
if(k==4)
{
for(int i=0;i<10&&i+sum<=m;i++)
for(int j=0;j<10&&j+sum+i<=m;j++)
{
int kk=m-i-j-sum;
if(kk>=10||kk<0)continue;
long long real=sum+i*10+j*100+kk*1000;
// cout<<"this real:"<<real<<endl;
compute(real+1);
}
}
else if(k==5)
{
for(int a=0;a<10&&a+sum<=m;a++)
for(int b=0;b<10&&b+sum<=m;b++)
for(int c=0;c<10&&c+sum<=m;c++)
{
int d=m-a-b-c-sum;
if(d>=10||d<0)continue;
long long real=sum+a*10+b*100+c*1000+d*10000;
compute(real+1);
}
}
else if(k==6)
{
for(int a=0;a<10&&a+sum<=m;a++)
for(int b=0;b<10&&b+sum<=m;b++)
for(int c=0;c<10&&c+sum<=m;c++)
for(int d=0;d<10&&d+sum<=m;d++)
{
int e=m-a-b-c-d-sum;
if(e>=10||e<0)continue;
long long real=sum+a*10+b*100+c*1000+d*10000+e*100000;
// cout<<"this real:"<<real<<endl;
compute(real+1);
}
}
else if(k==7)
{
for(int a=0;a<10&&a+sum<=m;a++)
for(int b=0;b<10&&b+sum<=m;b++)
for(int c=0;c<10&&c+sum<=m;c++)
for(int d=0;d<10&&d+sum<=m;d++)
for(int e=0;e<10&&e+sum<=m;e++)
{
int f=m-a-e-b-c-d-sum;
if(f>=10||f<0)continue;
long long real=sum+a*10+b*100+c*1000+d*10000+e*100000+f*1000000;
compute(real+1);
}
}else if(k==8)
{
for(int a=0;a<10&&a+sum<=m;a++)
for(int b=0;b<10&&b+sum<=m;b++)
for(int c=0;c<10&&c+sum<=m;c++)
for(int d=0;d<10&&d+sum<m;d++)
for(int e=0;e<10&&e+sum<=m;e++)
for(int f=0;f<10&&f+sum<=m;f++)
{
int g=m-a-f-e-b-c-d-sum;
if(g>=10||g<0)continue;
long long real=sum+a*10+b*100+c*1000+d*10000+e*100000+f*1000000+g*10000000;
compute(real+1);
}
}
else if(k==9)
{
for(int a=0;a<10&&a+sum<=m;a++)
for(int b=0;b<10&&b+sum<=m;b++)
for(int c=0;c<10&&c+sum<=m;c++)
for(int d=0;d<10&&d+sum<=m;d++)
for(int e=0;e<10&&e+sum<=m;e++)
for(int f=0;f<10&&f+sum<=m;f++)
for(int g=0;g<10&&g+sum<=m;g++)
{
int h=m-a-g-f-e-b-c-d-sum;
if(h>=10||h<0)continue;
long long real=sum+a*10+b*100+c*1000+d*10000+e*100000+f*1000000+g*10000000+h*100000000;
compute(real+1);
}
}
printf("Case %d\n",nn);
if(v.size()>0)
{
sort(v.begin(),v.end(),cmp);
for(int i=0;i<v.size();i++)
printf("%d %lld\n",v[i].n,v[i].a);
} else
printf("No Solution\n");
}
}