CF285C Building Permutation - 题解

思路

典型的贪心算法

如果要用最少的步骤把原数列改成从 \(1\)\(n\) 的有序数列,即:使数列里每个数与目标数列的差之和最小。所以可得:

  1. 将原数列排序

  2. 计算每个数与目标数列的差值

  3. 累加,输出答案

最终得到的答案是:

\[\sum\limits_{i=1}^n{\lvert a_i-i\rvert} \]

这样得到的答案必定最小,且时间复杂度为 \(O(n)\)

还有,累加到答案的过程中可能会超出 int 范围,所以答案变量应该使用 long long

其它细节见代码注释。

\(\textcolor{#52C41A}{\texttt{AC}}\) 代码

#include<cstdio>
#include<algorithm>	//包含快速排序函数 sort 
#include<cmath>		//包含绝对值函数 abs 
#define N 300005
using namespace std;

int n,a[N];
long long ans=0;	//答案变量开 long long 

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	sort(a+1,a+n+1);		//sort 快速排序函数 
	for(int i=1;i<=n;i++)
		ans+=abs(a[i]-i);	//注意“差值”不能单纯两数相减,要用绝对值函数 abs 
	printf("%lld\n",ans);
	return 0;
}

2022-07-06 21:41 撰写于洛谷,2025-08-29 20:22 迁移至博客园。

posted @ 2025-08-29 20:23  Jerrycyx  阅读(17)  评论(0)    收藏  举报