约素
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
題意很清楚, 無需多說什么。
我給出三種解法:
上面這個程序會導致超時, 經過多次測試, 我發現了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)==nif (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只有一個素因子, 素因子只能是整數, 于是得以上程序。
完。
總結
- 上一篇: Java使用poi将list<Map>导
- 下一篇: html图像标签、绝对路径和相对路径