蓝桥杯 算法提高游览计划

Posted 白龙码~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥杯 算法提高游览计划相关的知识,希望对你有一定的参考价值。

问题描述

在一条笔直的公路上有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;
/*
问题描述
  在一条笔直的公路上有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
 */ 
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;
	
	/* 思路:
	 * 2 * ΣΣ|ai-aj| / n 即为所求,证明如下: 
	 * 设两个景点ai和aj,根据排列组合,它们两个相邻访问的可能情况有2*(n-1)!种 
	 * 在这些情况中,它们俩对距离的贡献为|ai - aj|*2*(n-1)!
	 * 我们算出任意两个景点相邻的贡献和,即为总的游览路程,即 ΣΣ|ai-aj|*2*(n-1)!
	 * 而分母是总的情况n!,上下约分后得到2 * ΣΣ|ai-aj| / n
	 * 即分子为 2 * ΣΣ|ai-aj|,分母为n
	 * 上下进行约分后, 即可得到最终结果 
	 */
	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;	

以上是关于蓝桥杯 算法提高游览计划的主要内容,如果未能解决你的问题,请参考以下文章

算法训练 景点游览

蓝桥杯,算法提高,8皇后·改

蓝桥杯练习系统算法提高 求最大值

蓝桥杯 算法提高 递推求值

蓝桥杯 贪心模板 _算法提高 快乐司机

蓝桥杯 算法提高 8皇后·改 -- DFS 回溯