Gym 100796K Profact(爆搜+剪枝)

来源:互联网 发布:dronedeploy软件下载 编辑:程序博客网 时间:2024/05/08 01:25
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
    71238122425
    Output
    YESYESNOYESYESYESNO

    Hint

    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  __int64ll 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");    }}


    0 0
    原创粉丝点击