题解洛谷P4752 【Divided Prime】

此题的感想:我个人感觉这道题绿的有点假。。不过实际上是大佬们的程序我没看懂。这里想给大家普及一个新的思路。

算法:

①:我们知道,如果一个数的非1因数个数减去第二个数的非一因数个数>1的话,那么这两个数相除就一定不是质数。因为质数的因数除了1和本身就没有了,所以这是一种重要的条件,如果满足这种条件,就可以直接输出”No”,然后退出循环。
②:如果不符合条件①的话,那么我们可以开两个数组 a a b,并进行排序,因为a和b的长度差一肯定会有一个地方 a a b的数字不同,那么这个时候我们就可以退出循环,并记录这个下标,进行判断此数是否为质数,即可。

这样最差情况时间复杂度为 O(N) O ( N ) ,是可以通过此题的。我最慢一个点10ms。

话不多说,看代码:

#include<bits/stdc++.h>
#define MAXN 100010//定义最大值
using namespace std;
int n,i,j,x,m,t,t1,t2;
int a[MAXN],b[MAXN];
inline int read(){//快读
    int x=0;char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) x=x*10+c-48,c=getchar();
    return x; 
}
inline void write(int x){//快写
    if(x/10>0) write(x/10);
    putchar(x%10+48);
    return;
}
inline void printno(){//输出"NO"
    putchar('N');putchar('O');
    return;
}
inline void printyes(){//输出"YES"
    putchar('Y');putchar('E');putchar('S');return;
}
inline bool ps(int x){//判断质数
    int p=2;
    while(p<=round(sqrt(x))){
        if(x%p==0) return 0;
        p++;
    }
    return 1;
}
int main(){
    t=read();
    for(i=1;i<=t;i++){
        n=read();m=read(); //输入n,m
        memset(a,0,sizeof(a));memset(b,0,sizeof(b));
        //将数组清0
        t1=0;t2=0;  //非一元素个数清0
        for(j=1;j<=n;j++){
            x=read();
            if(x!=1) t1++,a[t1]=x; //如果此数不为1,那么就将其加入数组
        }  
        for(j=1;j<=m;j++){
            x=read();
            if(x!=1) t2++,b[t2]=x;//和输入a数组是一样的原理,这里不再描述
        }
        if(t1-t2!=1){//非一元素个数之差不为1,不可能为质数,直接输出NO,退出循环
            printno();cout<<endl;continue; 
        }
        sort(a+1,a+t1+1);//排序
        sort(b+1,b+t2+1);
        for(j=1;j<=t1;j++){
            if(a[j]!=b[j]) break;//当a数组该元素与b数组该元素不相等时,退出循环
        }
        if(ps(a[j-1])&&a[j-1]!=0){
        //若此数为质数,注意,我使用的判断素数方法0也会误判,所以这里我要加个特判,否则会WA两个点
            printyes();
            cout << endl;
            continue;
        }
        else{
            printno();//输出NO
            cout << endl;
            continue;
        }
    }
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值