LQ0019 数的拆分素数

Posted 海岛Blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LQ0019 数的拆分素数相关的知识,希望对你有一定的参考价值。

题目来源:蓝桥杯2022初赛 C++ A组I题,C++ G组F题

题目描述
给定T个正整数a,分别问每个ai能否表示为x1y1·x2y2的形式。
其中x1、x2为正整数,y1、y2为大于等于2的正整数。

输入格式
输入第一行包含一个整数T,表示询问次数。
接下来T行,每行一个正整数ai。
10% 的评测用例,1 ≤ T ≤ 200,ai ≤ 10^9;
30% 的评测用例,1 ≤ T ≤ 300,ai ≤ 10^18;
60% 的评测用例,1 ≤ T ≤ 10000,ai ≤ 10^18;
100%的评测用例,1≤ T ≤ 100000,1 ≤ ai ≤ 10^18。

输出格式
对于每次询问, 如果ai 能够表示为题目描述的形式则输出yes,否则输出no。

输入样例
7
2
6
12
4
8
24
72

输出样例
no
no
no
yes
yes
no
yes

问题分析
暴力分解的方法必定会超时,参加程序代码。
考虑用欧拉筛法,预先求出素数备用,试一下使用10000以内的素数。

超时的C语言程序(暴力)如下:

/* LQ0019 数的拆分 */

#include <stdio.h>

int judge(long long n)

    for (long long i = 2; i * i <= n; i++) 
        if (n % i == 0) 
            int cnt1 = 0;
            while (n % i == 0)
                cnt1++, n /= i;
            if (n == 1) 
                // n可以写成i^cnt1*1^2,则返回1
                if (cnt1 >= 2) return 1;
             else 
                for (long long j = i + 1; j * j <= n; j++)
                    if (n % j == 0) 
                        int cnt2 = 0;
                        while (n % j == 0)
                            cnt2++, n /= j;
                        if (n == 1) 
                            // n可以写成i^cnt1*j^cnt2,则返回1
                            if (cnt2 >= 2) return 1;
                        
                    
            
        
    
    return 0;


int main()

    int t;
    long long a;
    scanf("%d", &t);
    while (t--) 
        scanf("%lld", &a);

        printf("%s\\n", judge(a) ? "yes" : "no");
    

    return 0;

以上是关于LQ0019 数的拆分素数的主要内容,如果未能解决你的问题,请参考以下文章

D. Taxes分拆素数和

LQ0206 组素数枚举+素数

LQ0208 梅森素数大数

LQ0246 孪生素数程序填空

LQ0110 等差素数列无标题

LQ0041 特别数的和进制