LightOJ1028 1090 1138 Trailing Zeroes (I)(Ⅱ)(Ⅲ)[算數基本定理/打表/打表+二分]

C -  Trailing Zeroes (I)
Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu

Description

We know what a base of a number is and what the properties are. For example, we use decimal number system, where the base is 10 and we use the symbols - {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}. But in different bases we use different symbols. For example in binary number system we use only 0 and 1. Now in this problem, you are given an integer. You can convert it to any base you want to. But the condition is that if you convert it to any base then the number in that base should have at least one trailing zero that means a zero at the end.

For example, in decimal number system 2 doesn't have any trailing zero. But if we convert it to binary then 2 becomes (10)2 and it contains a trailing zero. Now you are given this task. You have to find the number of bases where the given number contains at least one trailing zero. You can use any base from two to infinite.

Input

Input starts with an integer T (≤ 10000), denoting the number of test cases.

Each case contains an integer N (1 ≤ N ≤ 1012).

Output

For each case, print the case number and the number of possible bases where N contains at least one trailing zero.

Sample Input

3

9

5

2

Sample Output

Case 1: 2

Case 2: 1

Case 3: 1

Hint

For 9, the possible bases are: 3 and 9. Since in base 39 is represented as 100, and in base 99 is represented as 10. In both bases, 9 contains a trailing zero.

題意:
T組數據,每組有一個N,求出N在多少個進位下末尾爲0

題解:
就是求出N的因數,但是不包括1

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
#define edge segtree[id]
#define lson segtree[id<<1]
#define rson segtree[id<<1|1]
using namespace std;
typedef long long ll;
const int N=1e6+5;
bool mark[N];
int prim[N];
int cnt;
//題目N取值 1<=N<=1e12
//T <=1e4
void initial()
{
    cnt=0;
    for (int i=2 ; i<N ; ++i)
    {
        if (!mark[i])
            prim[cnt++]=i;

        for (int j=0 ; j<cnt && i*prim[j]<N ; ++j)
        {
            mark[i*prim[j]]=1;
            if (!(i%prim[j]))
                break;
        }
    }
}
ll divi(ll n)
{
    ll ans=1;
    for (int i=0 ; i<cnt && prim[i]*prim[i]<=n ; ++i)
    {
        if (!(n%prim[i]))
        {
            int s=0;
            while (!(n%prim[i]))
            {
                n/=prim[i];
                s++;
            }
            ans*=(s+1);
        }
    }
    return n>1?ans*(1+1):ans;//n>1代表n爲素數 也是一個正因子 所以要加上
}
int main()
{
    initial();
    int T;
    scanf("%d",&T);
    for (int test=1 ; test<=T ; test++)
    {
        ll n;
        scanf("%lld",&n);
        printf("Case %d: %lld\n",test,divi(n)-1);//多了一個1因子 刪去
    }
    return 0;
}



H - Trailing Zeroes (Ⅱ)
Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu

Description

Find the number of trailing zeroes for the following function:

nCr * pq

where n, r, p, q are given. For example, if n = 10, r = 4, p = 1, q = 1, then the number is 210 so, number of trailing zeroes is 1.

Input

Input starts with an integer T (≤ 10000), denoting the number of test cases.

Each case contains four integers: n, r, p, q (1 ≤ n, r, p, q ≤ 106, r ≤ n).

Output

For each test case, print the case number and the number of trailing zeroes.

Sample Input

2

10 4 1 1

100 5 40 5

Sample Output

Case 1: 1

Case 2: 6



題意:
T組數據,給n,r,p,q 求出C(n,r)*(p^q)結果的末尾有多少個0

題解:
能弄出0的 只有2*5 那我只需要統計這個組合數有多少個2和多少個5,再加上(p^q)的2或者5的個數,取小的一邊
打表統計 1到1e6的數裏面有多少個2多少個5就可以了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
#define edge segtree[id]
#define lson segtree[id<<1]
#define rson segtree[id<<1|1]
using namespace std;
typedef long long ll;
const int N=1e6+5;
ll five[N],two[N];
void initial()
{
    memset(five,0,sizeof(five));
    memset(two,0,sizeof(two));
    ll s1=0,s2=0;
    for (int i=2 ; i<N ; ++i)
    {
        int num=i;
        while (!(num%2))
        {
            s1++;
            num/=2;
        }
        num=i;
        while (!(num%5))
        {
            s2++;
            num/=5;
        }
        two[i]=s1;
        five[i]=s2;
    }
}
int main()
{
    initial();
    int T;
    scanf("%d",&T);
    for (int test=1 ; test<=T ; ++test)
    {
        int n,r,p;
        ll q;
        scanf("%d%d%d%lld",&n,&r,&p,&q);
        ll ans = min (two[n]-two[n-r]-two[r]+(two[p]-two[p-1])*q,five[n]-five[n-r]-five[r]+(five[p]-five[p-1])*q);
        printf("Case %d: %lld\n",test,ans);
    }
    return 0;
}




K - Trailing Zeroes (III)
Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu

Description

You task is to find minimal natural number N, so that N! contains exactly Q zeroes on the trail in decimal notation. As you know N! = 1*2*...*N. For example, 5! = 120, 120 contains one zero on the trail.

Input

Input starts with an integer T (≤ 10000), denoting the number of test cases.

Each case contains an integer Q (1 ≤ Q ≤ 108) in a line.

Output

For each case, print the case number and N. If no solution is found then print 'impossible'.

Sample Input

3

1

2

5

Sample Output

Case 1: 5

Case 2: 10

Case 3: impossible



題意:
T組數據,每組有一個N,表示這個數的末尾有N個0,計算這是第幾個階乘纔會有N個0

題解:
跟上面一個題一樣,只有2*5纔會構成0在末尾,階乘中,2的個數肯定是比5大的,那我就不需要管2的個數,直接統計5的個數,打表統計1個5開始直到算到有超過1e8個5,統計過程過,因爲數組不能存那麼多,每隔100取記錄一次,然後二分查詢時,注意還原原來的數是乘以500,如果直接已經存在這個就直接輸出,區別開0-100 還有超過100的記法,如果剛剛好等於那麼多個0,輸出這個數,如果不存在就輸出'impossible' (我的這個解法大概是速度最慢了,因爲要先打表,網上貌似有其他解法,我沒有細看)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
#define edge segtree[id]
#define lson segtree[id<<1]
#define rson segtree[id<<1|1]
using namespace std;
typedef long long ll;
const int N=1e8;//最多1e8個0
const int M=1e6;
int sum[M];
int cnt;
void initial()//因爲2的個數肯定系夠的,甘姐系記錄5的個數就得了
{
    sum[0]=1;
    int res=0;
    cnt=0;
    for (int i=1 ; ; ++i)
    {
        if (!(i%5))//看這個數有多少5
        {
            int s=0,m=i;
            while (!(m%5))
            {
                s++;
                m/=5;
            }
            res+=(s+1);
        }
        else
            res+=1;
        if (!(i%100))
        {
            sum[i/100]=res;
            cnt++;
        }
        if (res>N)
            break;
    }
}
int main()
{
    initial();
    int T;
    scanf("%d",&T);
    for (int test=1 ; test<=T ; ++test)
    {
        int n;
        scanf("%d",&n);
        printf("Case %d: ",test);
        if (n==1)
        {
            printf("5\n");
            continue;
        }
        int ans=lower_bound(sum,sum+cnt,n)-sum-1;
        ll res=sum[ans];
        if (res==n)
        {
            printf("%lld\n",ans*500);
            continue;
        }
        ll last;
        if (!ans)
        {
            for (int i=2 ; ; ++i)
            {
                if (!(i%5))
                {
                    int s=0,m=i;
                    while(!(m%5))
                    {
                        s++;
                        m/=5;
                    }
                    res+=(s+1);
                }
                else
                    res++;
                if (res>=n)
                {
                    if (res==n)
                        last=i;
                    else
                        last=-1;
                    break;
                }
            }
        }
        else
        {
            last=ans*100;
            for (int i=last+1 ; ; ++i)
            {
                if (!(i%5))
                {
                    int s=0,m=i;
                    while (!(m%5))
                    {
                        s++;
                        m/=5;
                    }
                    res+=(s+1);
                }
                else
                    res++;
                if (res>=n)
                {
                    if (res==n)
                        last=i;
                    else
                        last=-1;
                    break;
                }
            }
        }
        if (last==-1)
            printf("impossible\n");
        else
            printf("%lld\n",last*5);
    }
    return 0;
}


發佈了51 篇原創文章 · 獲贊 15 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章