题目描述:
http://codeforces.com/gym/100796/problem/K
题解:
水题,但是还是傻了一会.
最开始一定会想,从大的可以整除的阶层往下除.但这是不对的. 比如fac[17]和fac[18], 不知道要不要除18,但是推一下就能发现,只有17 18 和 13 14 15 需要特殊考虑,其他的都是只除到那个质数就行了. 注意,一定是质数,不能多除
重点:
1.发现不定情况很少
2.其他情况只除到质数,而不是随便除
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn = 30 + 10;
const ll M = 1e18 + 100;
ll fac[maxn];
ll a, k;
int n;
int dfs(ll x) {
if(x == 1 || x == 2)
return 1;
int ans = 0;
if(x % 19 == 0) {
if(x % fac[19] == 0) {
return dfs(x / fac[19]);
}
return 0;
}
if(x % 17 == 0) {
if(x % fac[18] == 0)
ans += dfs(x / fac[18]);
if(x % fac[17] == 0)
ans += dfs(x / fac[17]);
if(ans > 0)
return 1;
return 0;
}
if(x % 13 == 0) {
if(x % fac[15] == 0)
ans += dfs(x / fac[15]);
if(x % fac[14] == 0)
ans += dfs(x / fac[14]);
if(x % fac[13] == 0)
ans += dfs(x / fac[13]);
if(ans > 0)
return 1;
return 0;
}
if(x % 11 == 0) {
if(x % fac[11] == 0) {
return dfs(x / fac[11]);
}
return 0;
}
if(x % 7 == 0) {
if(x % fac[7] == 0) {
return dfs(x / fac[7]);
}
return 0;
}
if(x % 5 == 0) {
if(x % fac[5] == 0) {
return dfs(x / fac[5]);
}
return 0;
}
if(x % 3 == 0) {
if(x % fac[3] == 0) {
return dfs(x / fac[3]);
}
return 0;
}
if(x % 2 == 0) {
if(x % fac[2] == 0) {
return dfs(x / fac[2]);
}
return 0;
}
return 0;
}
void solve() {
if(dfs(a) == 1)
printf("YES\n");
else
printf("NO\n");
}
int main() {
//freopen("k.txt", "r", stdin);
fac[1] = 1;
for(int i = 2; i <= 30; i++) {
// printf("111 %d\n", i);
if(fac[i - 1] >= M) {
//printf("%I64d %I64d **\n", fac[i - 1], M);
k = i - 1;
break;
}
fac[i] = fac[i - 1] * i;
}
//printf("%I64d %I64d %I64d\n", k, fac[k], fac[13]);
while(scanf("%d", &n) != EOF) {
for(int i = 0; i < n; i++) {
scanf("%I64d", &a);
solve();
}
}
return 0;
}