PAT(甲级)2019秋 Forever【最大公约数】

本文介绍了一种特殊的正整数——Forevernumber,它具有特定位数且满足数字和的约束条件。文章详细阐述了如何通过枚举和算法判断找到满足条件的所有Forevernumber,包括输入输出规格、样例输入输出及解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

“Forever number” is a positive integer AAA with KKK digits, satisfying the following constrains:

  • the sum of all the digits of AAA is mmm;
  • the sum of all the digits of A+1A+1A+1 is nnn; and
  • the greatest common divisor of mmm and nnn 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 NNN 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 KKK and mmm, first print in a line Case X, where Xis the case index (starts from 1). Then print nnn and AAA in the following line. The numbers must be separated by a space. If the solution is not unique, output in the ascending order of nnn. If still not unique, output in the ascending order of AAA. 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");


    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值