Codeforces Round #198 (Div. 2) C. Tourist Problem

首先比较容易得到的是对于n个目的地一共有n!种方案。也就是分母是n!,然后我们考虑一个问题,在每一种方案中一共有多少条路?这里一条路指的是从a点到达b点。

这个地方卡我了好久,刚才才想明白,其实一共有n条路。理由:so简单,因为一共有n个终点,每个终点都是一条路。

然后我们算一下,在这n!种方案中一共出现了多少条路?很明显,是n!*n条路。这时候重点来了,对于n个目的地来说,一共有多少条不同的路,也是好算,就是A(n,2),从n个点中挑出两个点,一个是起点,一个是终点。但是这其中要减去从1~n返回到0的路,因为0是不能作为终点的。这样我们就得到了一共n*n条路。而且这些路都是等价的,也就是说在这n!种方案中出现的次数是相同的。

这样的话,总的路出现的次数是n*n!,路的种类是n*n,那么每条路出现的次数也就是(n-1)!。

化简一下,分母就变成了n,分子就是所有的路的和。求这个和的时候需要用上一点儿小技巧,但是和前面的推论比起来就so easy了。

计算过程中需要注意会超int。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 500005
typedef long long LL;
LL a[N];
LL fun(LL x,LL y)
{
    LL k;
    if(x>y)
    {
        k=x;
        x=y;
        y=k;
    }
    k=1;
    while(k>0)
    {
        k=y%x;
        y=x;
        x=k;
    }
    return y;
}
int cmp(const void *a,const void *b)
{
    return *(int *)a-*(int *)b;
}
int main()
{
    LL am,az;
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int i;
        for(i=1;i<=n;i++)
            scanf("%I64d",&a[i]);
        qsort(a+1,n,sizeof(a[1]),cmp);
        am=n;
        LL x,y,z;
        x=0;
        z=0;
        for(i=1;i<=n;i++)
        {
            x+=(i-1)*a[i];
            z+=a[i];
        }
        y=0;
        int k=n-1;
        for(i=1;i<=n-1;i++)
        {
            y+=k*a[i];
            k--;
        }
        az=(x-y)*2;
        az+=z;
        LL m;
        m=fun(am,az);
        printf("%I64d %I64d\n",az/m,am/m);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值