题目连接: 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