Codeforces Contest 1114 problem C Trailing Loves (or L'oeufs?) —— 将1进制下的阶乘变成k进制,最后有几个0

91 篇文章 0 订阅

Aki is fond of numbers, especially those with trailing zeros. For example, the number 9200 has two trailing zeros. Aki thinks the more trailing zero digits a number has, the prettier it is.

However, Aki believes, that the number of trailing zeros of a number is not static, but depends on the base (radix) it is represented in. Thus, he considers a few scenarios with some numbers and bases. And now, since the numbers he used become quite bizarre, he asks you to help him to calculate the beauty of these numbers.

Given two integers n and b (in decimal notation), your task is to calculate the number of trailing zero digits in the b-ary (in the base/radix of b) representation of n! (factorial of n).

Input
The only line of the input contains two integers n and b (1≤n≤1018, 2≤b≤1012).

Output
Print an only integer — the number of trailing zero digits in the b-ary representation of n!
Examples
inputCopy
6 9
outputCopy
1
inputCopy
38 11
outputCopy
3
inputCopy
5 2
outputCopy
3
inputCopy
5 10
outputCopy
1
Note
In the first example, 6!(10)=720(10)=880(9).

In the third and fourth example, 5!(10)=120(10)=1111000(2).

The representation of the number x in the b-ary base is d1,d2,…,dk if x=d1bk−1+d2bk−2+…+dkb0, where di are integers and 0≤di≤b−1. For example, the number 720 from the first example is represented as 880(9) since 720=8⋅92+8⋅9+0⋅1.

You can read more about bases here.

题意:

给你一个数n,问你n!在k进制下最后有几个0.

题解:

我们看看这个样例,在自己编几个,就会发现,6 9是 123456在9进制下,最后0的个数是1,我们发现里面有两个3,组成了一个9,发现了什么?然后我又造了一个4 2,是1234 在二进制下,是11000,有3个0,2*4是 2 3 2^3 23,那么答案就明了了。我们枚举k的每一个因子,看看这个因子的一次方,二次方,三次方。。。,n/这些树分别有多少个,再加起来,举个例子:8 2,有用的就是 2 4 6 8, 8/2=4,8/4=2,8/8=1,这些加起来正好就是他们的幂次。最后在所有因子里取最小的即可,因为少了某种因子就不能再是它的倍数了。

#include<bits/stdc++.h>
using namespace std;
#define pa pair<int,int>
char mp[105][15];
int n,k;

int xmov[]={1,0,-1,0};
int ymov[]={0,1,0,-1};
void bfs(int sx,int sy,char col)
{
    queue<pa>Q;
    Q.push({sx,sy});
    mp[sx][sy]='0';
    while(!Q.empty())
    {
        int x=Q.front().first,y=Q.front().second;
        Q.pop();
        for(int i=0;i<4;i++)
        {
            int nx=x+xmov[i];
            int ny=y+ymov[i];
            if(nx<1||nx>n||ny<1||ny>10||mp[nx][ny]!=col)
                continue;
            mp[nx][ny]='0';
            Q.push({nx,ny});
        }
    }
}
int check(int x,int y)
{
    queue<pa>Q;
    Q.push({x,y});
    int vis[105][15]={0};
    vis[x][y]=1;
    int sum=1;
    while(!Q.empty())
    {
        pa now=Q.front();
        Q.pop();
        for(int i=0;i<4;i++)
        {
            int nx=now.first+xmov[i];
            int ny=now.second+ymov[i];
            if(nx<1||nx>n||ny<1||ny>10||mp[nx][ny]!=mp[x][y]||vis[nx][ny])
                continue;
            vis[nx][ny]=1;
            if(sum+1>=k)
                return 1;
            sum++;
            Q.push({nx,ny});
        }
    }
    return 0;
}
void fall()
{
    int low;
    for(int i=1;i<=10;i++)
    {
        low=n;
        for(int j=n;j>=1;j--)
        {
            if(mp[j][i]=='0')
                continue;
            if(low!=j)
                mp[low][i]=mp[j][i],mp[j][i]='0';
            low--;
        }
    }
    /*for(int i=1;i<=n;i++)
                    {
                        for(int j=1;j<=10;j++)
                            printf("%c",mp[i][j]);
                        printf("\n");
                    }*/
}
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
        scanf("%s",mp[i]+1);
    int flag=1;
    while(flag)
    {

        fall();
        flag=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=10;j++)
            {
                if(mp[i][j]=='0')
                    continue;
                if(check(i,j))
                {
                    bfs(i,j,mp[i][j]),flag=1;
                    /*for(int i=1;i<=n;i++)
                    {
                        for(int j=1;j<=10;j++)
                            printf("%c",mp[i][j]);
                        printf("\n");
                    }*/

                }
            }
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=10;j++)
            printf("%c",mp[i][j]);
        printf("\n");
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值