HDU 3998 Harry Potter and the Hide Story【数学】

Harry Potter and the Hide Story

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2829    Accepted Submission(s): 718


Problem Description
iSea is tired of writing the story of Harry Potter, so, lucky you, solving the following problem is enough.

 

Input
The first line contains a single integer T, indicating the number of test cases.
Each test case contains two integers, N and K. 

Technical Specification

1. 1 <= T <= 500
2. 1 <= K <= 1 000 000 000 000 00
3. 1 <= N <= 1 000 000 000 000 000 000
 

Output
For each test case, output the case number first, then the answer, if the answer is bigger than 9 223 372 036 854 775 807, output “inf” (without quote).
 

Sample Input
  
  
2 2 2 10 10
 

Sample Output
  
  
Case 1: 1 Case 2: 2

解题思路:

把K分解质因素,求出每个因数在n!中有多少个,然后个数再除以该因素在K中的个数,去最小值就是答案了。  题目要求大于9 223 372 036 854 775 807要用inf输出,
9 223 372 036 854 775 807=2^63-1,用unsigned long long 存答案即可,K=1要特判。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<map>
#include<string>
#include<queue>
#include<vector>
#include<list>
#include<bitset>
//#pragma comment(linker,"/STACK:1024000000,1024000000")
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
ll K,n;
int prime[10000005],cur;
ll fac[105];
int num[105];
const ull INF = 9223372036854775808ull;
//500000000000000000
//999999999999999976
//9223372036854775808
void getfac(ll n)
{
    fac[0]=0;
    ll &cnt=fac[0];
    for(int i=0;i<cur;i++)
    {
        if((ll)prime[i]*prime[i]>n) break;
        if(n%prime[i]==0)
        {
            fac[++cnt]=prime[i];
            num[cnt]=0;
            while(n%prime[i]==0) n/=prime[i],num[cnt]++;;
        }

    }if(n>1) {fac[++cnt]=n;num[cnt]=1;}
}
ull get(ll d)
{
    ull ans=0;
    for(ull i=d;;i*=d)
    {
        ans+=n/i;
        if(i>n/d) break;
    }
    return ans;
}
int main()
{
    cur=0;
    memset(prime,0,sizeof prime);
    for(int i=2;i<10000005;i++)
    {
        if(!prime[i]) prime[cur++]=i;
        for(int j=0;j<cur;j++)
        {
            if(i*prime[j]>=10000005) break;
            prime[i*prime[j]]=1;
            if(i%prime[j]==0) break;
        }
    }
    int t,tt=0;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%I64d%I64d",&n,&K);
        ll Max=0;
        if(K==1)
        {
            printf("Case %d: inf\n",++tt);
            continue;
        }
        getfac(K);
        ull Min=INF;
        for(int i= 1;i<=fac[0];i++)
        {
            ull cnt=get(fac[i]);
            cnt/=num[i];
            Min=min(Min,cnt);
        }
        if(Min>=INF)  printf("Case %d: inf\n",++tt);
        else printf("Case %d: %I64u\n",++tt,Min);
    }
   return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值