约素
来源:互联网 发布:淘宝店铺代码 编辑:程序博客网 时间:2024/04/20 09:04
http://oj.acm.zstu.edu.cn/JudgeOnline/problem.php?id=4274
4274: 约素
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 1890 Solved: 493
Description
判断一个正整数n的约数个数是否为p,其中p是素数。
Input
第一行给测试总数T(T <= 10000)。
接下来有T行,每行有两个数字n(1 <= n <= 1000000000)和p(2 < p <= 1000000000)。
Output
每组测试数据输出一行,如果n的约数个数是p,输出“YES”,否则输出“NO”。
Sample Input
5
64 7
911 233
1080 13
1024 11
20170211 1913
Sample Output
YES
NO
NO
YES
NO
题意很清楚, 无需多说什么。
我给出三种解法:
第一种:超时的。(数据组数太多)#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cstdlib>#include <cmath>#include <string>#include <vector>#include <map>#include <set>#include <queue>#include <stack>using namespace std;typedef long long LL;int n, p;int main(){ int t; for (scanf("%d", &t); t; t--){ scanf("%d%d", &n, &p); int cnt=1; for (LL i=2; i*i<=n; i++){ if (n%i==0){//找到一个素因子 int num=0; while (n%i==0) { num++; n/=i; } cnt*=(1+num);//算术基本定理的结论 } } if (n!=1){ cnt*=2;//必不可少 } if (cnt!=p) printf("NO\n"); else printf("YES\n"); } return 0;}
第二种:(预处理, 时间复杂度是没有问题的, 但是还是超时了,因为程序有错)首先给出一个错误的程序:#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cstdlib>#include <cmath>#include <string>#include <vector>#include <map>#include <set>#include <queue>#include <stack>using namespace std;typedef long long LL;int N, P;const LL maxn=1e6;bool prime[maxn];LL p[maxn];LL cn;void cnt_prime(){ cn=0; memset(prime, 0, sizeof prime); for (LL i=2; i<maxn; i++){ if (!prime[i]){ p[cn++]=i;if (cn==1) for (LL j=i*i; j<=maxn; j+=i) {//这里出现了一个不那么显然的错误, 一不小心就gg了 prime[j]=true; } } }}int main(){ int t; cnt_prime();cout<<p[0]<<endl; for (scanf("%d", &t); t; t--){ scanf("%d%d", &N, &P); LL cnt=1; for (LL i=0; i<cn && p[i]*p[i]<=N; i++){ if (N%p[i]==0){ LL num=0; while (N%p[i]==0) { num++; N=N/p[i]; } cnt*=(1+num); } } if (N>1){ cnt*=2; } if (cnt!=P) printf("NO\n"); else printf("YES\n"); } return 0;}
上面这个程序会导致超时, 经过多次测试, 我发现了p[0]==1!!!! 是的, 其它的素数都对了, 但第一个素数应该是2。想不到原因啊!(临时把p[0]强制赋值为2当然是可以AC了, 但是为什么会出现p[0]==1呢?)很无奈, 问了别人, 也是看不出来。好吧,最终还是硬着头皮一句一句分析找原因, 原来是“j<=maxn”这里考虑不周:当j==maxn时, prime[maxn]=true; 也就是p[0]=true=1! Orz…因为prime的下标只能去到maxn-1, 所以prime[maxn]对应的地址就是p[0]的地址。这种问题, 我以前给别人看程序的时候出现过一次, 也是花了很多时间才找出来的。 没想到这次再次出现了还是不能一眼察觉。。。还是不够细心严谨啊, 这就是教训!所以把“j<=maxn” 中的等号去掉即可AC。
第三种方法:(应该是最高效的了吧)#include <iostream>#include <cmath>#include <cstdio>using namespace std;const double eps=1e-8;typedef long long LL;bool is_prime(int x){ if (x<2) return false; if (x==2 || x==3) return true; for (LL i=2; i*i<=x; i++){ if (x%i==0) return false; } return true;}int main(){ int t; for (scanf("%d", &t); t; t--){ int n, p; scanf("%d%d", &n, &p); int x=pow(n+0.5, 1.0/(p-1));//p是素数,=> n只有一个素因子x,=> p=(1+p-1); => x^(p-1)==n if (fabs(pow(x, p-1)-n)<eps && is_prime(x)) printf("YES\n"); else printf("NO\n"); } return 0;}
第三个程序成立的必要条件是p是素数, 这个是题目给的。 若n=p0^e0 + p1^e1 + … + pi^ei;
则p=(1+e0)* (1+e1) * … *(1+ei) => p只有一个素因子, 素因子只能是整数, 于是得以上程序。
完。
- 约素
- 约素
- 约素
- zstuoj 4274 约素
- 4274: 约素
- ZSTU4274 约素
- Problem I: 约素
- 4274: 约素
- zstu4274-约素
- ZSTU 4274 约素 约数,不是因子啊!
- 约真分数
- zstu oj 4274 约素(求一个数约数的个数)(暴力法)
- 原创:标准之约
- 问题的归约
- 玫瑰之约
- 公 司 公 约
- 如何约网友上床!!
- 与阳春约
- Java算法大全
- iOS 修改文件的名称
- Java异常之图书管理系统
- 1026. 程序运行时间(15) python篇
- 后台进程与守护进程区别
- 约素
- VC知识库视频大讲坛系列之GDI GDI+从入门到精通
- c++ 指针、常量指针、指针常量、引用的简单介绍
- 蓝桥杯-运动员分组
- 2014年传智Itcast C++培训3期视频全套
- Android之Glide(非常好用的图片加载框架)
- CentOS7 Docker 各种配置
- Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: 没有为参数号 2 设置值
- Java之构造方法的重载