您的位置:首页 > 理论基础

湖南省第十一届大学生计算机程序设计竞赛—阶乘除法

2017-07-05 16:26 295 查看


D - 阶乘除法

 

输入两个正整数 n, m,输出 n!/m!,其中阶乘定义为 n!=
1*2*3*...*n (n>=1)。 比如,若 n=6, m=3,则n!/m!=6!/3!=720/6=120。

是不是很简单?现在让我们把问题反过来:输入 k=n!/m!,找到这样的整数二元组(n,m)
(n>m>=1)。

如果答案不唯一,n 应该尽量小。比如,若 k=120,输出应该是 n=5, m=1,而不是 n=6, m=3,因为5!/1!=6!/3!=120,而 5<6。

Input
输入包含不超过 100 组数据。每组数据包含一个整数 k (1<=k<=10^9)。

Output
对于每组数据,输出两个正整数 n 和 m。无解输出"Impossible",多解时应让 n 尽量小。

Sample Input
120
1
210


Sample Output
Case 1: 5 1
Case 2: Impossible
Case 3: 7 4


Hint

代码:
#include <iostream>

#include <stdio.h>

#include <string.h>

#include <math.h>

using namespace std;

typedef long long LL;

int main()

{

    LL k;

    LL t = 1;

    while(scanf("%lld",&k)!=EOF)

    {

        LL n = (LL)sqrt(k)+10;

        LL l = 1,r =2,sum=1;

        LL ans1=k-1,ans2=k;

        bool flag = true;

        while(l<n)

        {

            while(r<n&&sum<k)

            {

                sum*=r;

                r++;

            }

            if(sum==k)

            {

                ans1 = l;

                ans2 = r-1;

                flag = false;

                break;

            }

            sum=sum/l;

            l++;

        }

        if(!flag)

        {

            if(ans1!=1) ans1--;

        }

        printf("Case %lld: ",t++);

        if(k==1)

        {

            printf("Impossible\n");

        }else

        {

            printf("%lld %lld\n",ans2,ans1);

        }

    }

    return 0;

}

代码二:
#include<stdio.h>

#include<string.h>

int y[1000000], cnt;

void f(int k)

{

    cnt = 0;

    for (int i = 2; i*i <= k; ++i)

        {

            if (k%i == 0)

            {

                y[cnt++] = i;

            }

        }

    y[cnt++] = k;

}

int main()

{

    int cas = 0, k;

    while (scanf("%d",&k)!=EOF)

    {

        if (k == 1)

        {

            printf("Case %d: Impossible\n",++cas);

            continue;

        }

        int n, m;

        f(k);

        for (int i = 0; i < cnt; ++i)

            {

                m = y[i] - 1;

                n = y[i];

                int t = k;

                while (t != 1)

                {

                    if (t%n == 0)

                    {

                        t /= n;

                        n++;

                    }

                    else

                        break;

                }

                if (t == 1)

                    break;

            }

        printf("Case %d: %d %d\n", ++cas, n - 1, m);

    }

    return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐