Gym - 100796K Profact 阶乘的乘积 DFS+剪枝
2017-03-11 14:55
176 查看
2015-2016 ACM ICPC Baltic Selection Contest
K. Profacttime limit per test:1 second
memory limit per test:256 megabytes
Alice is bored out of her mind by her math classes. She craves for something much more exciting. That is why she invented a new type of numbers, theprofacts. Alice calls a positive integer number a profact if it can
be expressed as a product of one or several factorials.
Just today Alice received n bills. She wonders whether the costs on the bills are profact numbers. But the numbers are too large, help Alice check this!
Input
The first line contains a single integer n, the number of bills (1 ≤ n ≤ 105). Each of the nextn lines contains
a single integer ai, the cost on the
i-th bill (1 ≤ ai ≤ 1018).
Output
Output n lines, on the
i-th line output the answer for the number
ai. If the number
ai is a profact, output "YES", otherwise output "NO".
Examples
Input
7 1 2 3 8 12 24 25
Output
YES YES NO YES YES YES NO
Note
A factorial is any number that can be expressed as1·2·3·...·k, for some positive integer
k, and is denoted by
k!.
先输入总共有几组数据,然后每组数据一个数字,判断这个数字是否可以通过一个或多个阶乘数的乘积得到,比如8=2!*2!*2!。可以就输出YES,不可以输出NO,然后问题就在于如何判断了,因为题目范围是10^18,所以提前打了个表看了一下,19!就已经大于10^18了,所以先打表打到19的阶乘都得出来然后再进行处理。
之后用dfs不断对这个数字取余判断就可以了,如果能顺利除到1就是可以的,如果不能就不可以。当然直接暴力的话肯定是会超时的,简单的剪枝就不说了,比较关键的是对一些素数阶乘的处理,如果在这个数中存在素数,就一定要用素数!来进行处理,否则一定不能满足题目条件。
下面AC代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; long long fac[25]; int t; int pri[10]={2,3,5,7,11,13,17,19}; int know() { int i; fac[0]=1; for(i=1;i<20;i++) { fac[i]=fac[i-1]*(i+1); //cout<<fac[i]<<endl; } return 0; } int dfs(long long a,int b) { int i,j; if(t==1) return 0; if(a==1) { t=1; return 0; } for(i=b;i>=2;i--) { if(a%fac[i-1]==0) { dfs(a/fac[i-1],i); if(t==0) { for(j=0;j<8;j++) { if(pri[j]==i) return 0; if(pri[j]>i) break; } } } if(t==1) return 0; } return 0; } int main() { int T; long long n; int i; know(); scanf("%d",&T); while(T--) { t=0; scanf("%lld",&n); dfs(n,20); if(t==1) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }
相关文章推荐
- Gym 100796K Profact
- Gym 100796K Profact(爆搜+剪枝)
- (转载)求解阶乘乘积的最右非零值
- Codeforces GYM 100548 F - Color 2014-2015 ACM-ICPC, Asia Xian Regional Contest
- 大数阶乘
- 【SzNOI语法百题】【d041】计算阶乘n!
- Gym - 100520D
- 给定一个整数N,那么N的阶乘N!末尾有多少个0呢?例如:N=10,N!=3628800,N!的末尾有两个0。
- Codeforces gym 101102 K 想法
- 算法提高 最大乘积
- 【数论】洛谷 P1134 阶乘问题
- 基础练习 阶乘计算
- Gym - 101341D Jumps
- 最小乘积
- N的阶乘
- 14-语言入门-14-阶乘因式分解(一)
- Gym - 100765A Sasha vs. Kate 思维
- 九度 1076 N的阶乘(模拟)
- Algorithm学习笔记 --- 大数阶乘算法模板
- Hdu 10000的阶乘