【蓝桥杯每日一题】数的拆分——筛质数

数的拆分

2024-12-12 数的拆分 筛质数 思维

题目大意

给定 ( T ) 个正整数 a i a_i ai,分别问每个 a i a_i ai 能否表示为 x 1 y 1 ⋅ x 2 y 2 x_1^{y_1} \cdot x_2^{y_2} x1y1⋅x2y2 的形式,其中 x 1 , x 2 x_1, x_2 x1,x2为正整数, y 1 , y 2 y_1, y_2 y1,y2为大于等于 2 的正整数。

解题思路

乍一看题目非常好理解!又一看嘎嘣住了!!!来听我慢慢分析

  1. 由这个分解的形式有没有发现似曾相识,就是---分解质因数,只不过这个只分解成了两个,那么根据分解质因数来思考;因为题目中没有要求 x 1 , x 2 x_1,x_2 x1,x2 一定要是质数(虽然在样例中都分解成了质数,那这不正是在暗示你吗?),那么如果一个数分解成了好几个质因子的成绩,我们有没有办法让他合并成两个呢?

    例 :

    x = 2 4 ∗ 3 3 ∗ 5 7 x=2^4*3^3*5^7 x=24∗33∗57,则 x = ( 2 ∗ 5 ) 4 ∗ ( 3 ∗ 5 ) 3 x=(2*5)^4*(3*5)^3 x=(2∗5)4∗(3∗5)3这样不就满足条件了吗,其他的同样也可以构成两个数的幂成绩;

  2. 但是,上面说的是可构造的条件,那么当分解的质因数中包含幂指数为1的值,之后不满足题目构造条件

  3. 还有一种构造条件,值分解成了一个质因数的分解,那么另一个数就可以用1来补充。

  4. 另外补充一个常识,任何大于1 的数都可以通过2或者3 来构造出来,那么对于只有一个因数的值,可以判断当前值是否可以开2次方或者3次方

  5. 可以先去了解下分解质因数 的思想,并且学习一下埃氏筛法筛质数

Accepted
cpp 复制代码
/*
    通过筛法去除一定范围内的素数,然后判断其分解的数中的次幂的值即可,还要在前后判断是否
    可以开2次方或者是三次方
*/

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N = 10000;
int st[N],primes[N];    // 第二个是存素数的,第一个表示当前值的状态的
int t;  // 表示素数的数量

// 判断平方
bool check (ll x) {
    ll y = sqrtl(x);
    if(y*y == x) return true;
    return false;
}

// 判断三次方
bool check1(int x) {
    ll y = pow(x,1.0/3);
    while(y*y*y <= x) {
        if(y*y*y == x) return true;
        y++;
    }
    return false;
}

// 埃氏筛法
void find_primes() {
    st[1] = 1;
    for(int i = 2;i <= N;i++) {
        if(!st[i]) {
            primes[t++] = i;
            // 只筛出来i 的倍数
            for(int j = i+i;j < N;j+= i) {
                st[j] = true;
            }
        }
    }
}

void sovle () {
    ll n;cin>>n;
    
    // 判断是否为次方形式
    if(check(n) || check1(n)) {
        cout<<"yes"<<endl;
        return ;
    }
    // 遍历所有的质数
    for(int i = 0;i < t;i++) {
        if(n % primes[i]) continue;
        int cnt = 0;
        // 除去质数
        while(n%primes[i]==0) {
            cnt++;
            n /= primes[i];
        }
        // 时刻判断着 是否存在一个质因数的幂次为1 
        if(cnt == 1) {
            cout<<"no"<<endl;
            return ;
        }
    }
    // 判断最后剩余的数是否2次方或者是三次方
    if(check(n) || check1(n)) {
        cout<<"yes"<<endl;
    }else {
        cout<<"no"<<endl;
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    find_primes();
    int T; cin>>T;
    while(T--) sovle();
    return 0;
}
思考

这个题相对于上一个带权并查集好理解一些,但是考察的也是思维,还有实现的数学方法,多思考多动手!!!

备注

想要一起备赛的同学可以在评论区留言!!!

相关推荐
Coovally AI模型快速验证33 分钟前
MMYOLO:打破单一模式限制,多模态目标检测的革命性突破!
人工智能·算法·yolo·目标检测·机器学习·计算机视觉·目标跟踪
可为测控1 小时前
图像处理基础(4):高斯滤波器详解
人工智能·算法·计算机视觉
Milk夜雨2 小时前
头歌实训作业 算法设计与分析-贪心算法(第3关:活动安排问题)
算法·贪心算法
BoBoo文睡不醒2 小时前
动态规划(DP)(细致讲解+例题分析)
算法·动态规划
apz_end2 小时前
埃氏算法C++实现: 快速输出质数( 素数 )
开发语言·c++·算法·埃氏算法
仟濹3 小时前
【贪心算法】洛谷P1106 - 删数问题
c语言·c++·算法·贪心算法
CM莫问4 小时前
python实战(十五)——中文手写体数字图像CNN分类
人工智能·python·深度学习·算法·cnn·图像分类·手写体识别
sz66cm4 小时前
LeetCode刷题 -- 45.跳跃游戏 II
算法·leetcode
Amor风信子4 小时前
华为OD机试真题---战场索敌
java·开发语言·算法·华为od·华为
old_power5 小时前
【PCL】Segmentation 模块—— 基于图割算法的点云分割(Min-Cut Based Segmentation)
c++·算法·计算机视觉·3d