问题描述
在一条笔直的公路上有n个景点,第i个景点在Ai千米处,起点在0千米处,所有景点都位于起点一侧。从起点出发,每次任选一个没有游览的景点,从当前位置出发到达那个景点游览这样进行n次,直到停在最后游览的那个景点。(最后不会回到起点。)在x千米处的点与在y千米处的点的路程为|x-y|千米。 平均的总游览路程是多少?她选择所有游览路线的概率是相等的,你可以认为这个概率等于1/n!。
输入格式
第一行一个数n,第二行n个数A1, A2 … An,如题目所述。 2<n<100000,1≤Ai<10^7,对于任意1≤i<n,都有Ai<A(i+1)。
输出格式
输出一行,两个数,答案的分子和分母。要求分子分母不能再约分。
样例输入
3 2 3 5
样例输出
22 3
思路分析
设两个景点ai和aj,根据排列组合,它们两个相邻访问的可能情况有2*(n-1)!种。在这些情况中,它们俩对距离的贡献为|ai - aj|×2×(n-1)!
我们算出任意两个景点相邻的贡献和,即为总的游览路程:ΣΣ|ai-aj|2(n-1)! 而分母是总的情况n!,上下约分后得到2 × ΣΣ|ai-aj| / n 即分子为 2 * ΣΣ|ai-aj|,分母为n
根据题目要求,要求分子分母不能再约分,因此循环除以分子分母的最大公约数,直到最大公约数为1
代码实现
#include <bits/stdc++.h>
using namespace std;
int n, tmp;
typedef long long ll;
ll gcd(ll a, ll b)
{
return b == 0 ? a : gcd(b, a % b);
}
int main()
{
scanf("%d", &n);
vector<int> a(n);
for (int i = 0; i < n; ++i)
{
scanf("%d", &tmp);
a[i] = tmp;
}
long long x = 0;
for (int i = 0; i < n; ++i)
{
x += a[i];
for (int j = i + 1; j < n; ++j)
{
x += 2 * (a[j] - a[i]);
}
}
int res;
long long y = n;
while ((res = gcd(x, y)) != 1)
{
x /= res;
y /= res;
}
cout << x << " " << y << endl;
return 0;
}
|