題目連接: hrbust 1328php
這是一道數論的題目,求解方法仍是挺巧妙的,儘管夠基礎。ios
首先要知道的是多個數的最小公倍數究竟怎麼求,有一個公式爲lcm(a, b, c) = lcm(lcm(a,b),c),這個公式對n個數同樣也成立。 還有一種求法,是將這多個數均寫成素數因子的冪相乘的形式(惟一分解定理),而後對每一個素數因子,只取最大的指數,相乘就是最小公倍數了。算法
這裏用的是第二種想法,其實這種想法也是夠直觀,最接近直覺的。若是A(n)和A(n-1)是相等的,那麼說明n的素數因子冪相乘的形式中,沒有一個素數因子的冪是大於A(n-1)對應素數的冪的。 而若是n含有兩個及以上素數因子,好比(a^x)*(b^y),那x和y均不會超過A(n-1)對應素數的冪,由於a^x和b^y都是小於n的,A(n-1)中a和b的指數必定大於等於x和y。若是n能夠寫成a^x這種形式,那麼在A(n-1)的a因子的指數必定不會超過x,由於這麼大的指數是第一次出現的(特別地,當x爲1時,n爲素數)。spa
#include <cstdio> #include <vector> #include <iostream> using namespace std; vector<int> primes; int not_prime[1010]; int main() { for(int i = 2; i <= 1000; i++) { if(!not_prime[i]) { primes.push_back(i); for(int j = 2; j*i <= 1000; j++) not_prime[i*j] = 1; } } int T; cin >> T; while(T--) { int n; scanf("%d", &n); if(n < 6) { printf("NO\n"); continue; } int yep = 1, cnt = 0; for(int i = 0; i < primes.size() && primes[i] * primes[i] <= n; i++) { if(n % primes[i]) continue; cnt++; int n_ = n; while(n_ % primes[i] == 0) n_ /= primes[i]; if(n_ == 1) { yep = 0; break; } } if(yep && cnt) printf("YES\n"); else printf("NO\n"); } return 0; }
代碼裏用了素數篩查,n的規模是1000000,它的素數因子絕對會超過1000,這麼篩不會超時。code
其實算法裏面我最討厭的就是數論,由於我對這類題目不太敏感,每次出我都不知道該往哪想。可是即便不去專門搞數論,相似gcd、lcm、同餘、篩素數這樣的東西最好也要知道,我見過一些題目把數論融了進去,若是一點數論都不懂極可能會無從下手。ci