Gym 100796K Profact(爆搜+剪枝)
2015-11-14 21:48
337 查看
K - Profact
Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d
& %I64u
Submit Status Practice Gym
100796K
Description
standard input/output
Announcement
Statements
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, the profacts. 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 next n 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".
Sample Input
Input
Output
Hint
A factorial is any number that can be expressed as 1·2·3·...·k, for some positive integer k,
and is denoted by k!.
题目大意:
输入一个数,问这个数能不能表示为1个或者多个阶乘的乘积。
范围:
a<=10^18。
思路:
可以知道20的阶乘已经超过了10^18,所以我们可以先预处理出来前20的阶乘。然后我们可以对这个数进行爆搜。
但是,这样是TLE!!!
所以考虑加剪枝,举个栗子:我们可以想到,假设如果这个数n能够被19!整除,但是他最后不能被其他阶乘整除了,此时我们没有达到目的。在搜索回溯的过程中,我们重新回到起点,回去判断能否被18!整除。但是!我们根本就不需要再去判了,因为这个数如果能被19!整除,那一定能被18!整除,前面那个不能成功,后者也一定是会失败的。所以此时我们就直接return了。
代码:
Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d
& %I64u
Submit Status Practice Gym
100796K
Description
standard input/output
Announcement
Statements
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, the profacts. 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 next n 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".
Sample Input
Input
7 1 2 3 8 12 24 25
Output
YES YES NO YES YES YES NO
Hint
A factorial is any number that can be expressed as 1·2·3·...·k, for some positive integer k,
and is denoted by k!.
题目大意:
输入一个数,问这个数能不能表示为1个或者多个阶乘的乘积。
范围:
a<=10^18。
思路:
可以知道20的阶乘已经超过了10^18,所以我们可以先预处理出来前20的阶乘。然后我们可以对这个数进行爆搜。
但是,这样是TLE!!!
所以考虑加剪枝,举个栗子:我们可以想到,假设如果这个数n能够被19!整除,但是他最后不能被其他阶乘整除了,此时我们没有达到目的。在搜索回溯的过程中,我们重新回到起点,回去判断能否被18!整除。但是!我们根本就不需要再去判了,因为这个数如果能被19!整除,那一定能被18!整除,前面那个不能成功,后者也一定是会失败的。所以此时我们就直接return了。
代码:
#include<stdio.h> #include<string.h> #define ll __int64 ll as[]={ 0,1,2,6,24,120,720,5040, 40320, 362880 , 3628800 , 39916800, 479001600 , 6227020800 , 87178291200, 1307674368000 , 20922789888000 , 355687428096000 , 6402373705728000, 121645100408832000 , 2432902008176640000 },xx[8]={2,3,5,7,11,13,17,19}; int flag=0; void dfs(ll x,ll q) { if(flag)return; if(x==1){ flag=1; return; } if(flag==1)return; for(int i=q;i>=2;i--) { if(x%as[i]==0){dfs(x/as[i],i); if(!flag){ for(int j=0;j<8;j++) { if(xx[j]==i)return; if(xx[j]>i)break; } } } if(flag)return; } } int main() { //for(int i=1;i<=20;i++) // printf("%I64d\n",as[i]); ll n,a,i,j,k; scanf("%I64d",&n); while(n--) { scanf("%I64d",&a); if(a==1){ printf("YES\n"); continue; } flag=0; dfs(a,20); if(flag)printf("YES\n"); else printf("NO\n"); } }
相关文章推荐
- C++实现单链表
- SYN及SYN攻击
- 最新破解Wordpress后台密码的方法
- 计算机的大端模式和小端模式
- 单例模式-Singleton
- BestCoder Round #62 (div.2)-Clarke and food(模拟)
- iOS基于百度地图的开发(3)——地址搜索
- IOS开源库一览表
- 常见的设计模式(八)——桥接模式
- 适配器模式-Adapter
- centos 的yum仓库搭建
- [OpenCV] -- win7下配置OpenCV的Qt开发环境
- POJ 2352 【树状数组】
- STL: lower_bound, upper_bound用法(C++)
- 九度OJ 1335:闯迷宫 (BFS)
- Android Studio简单设置
- mybatis使用@param后掉的坑
- 九度OJ 1335:闯迷宫 (BFS)
- stdint.
- Java面试宝典-assert