CF285C Building Permutation - 题解
思路
典型的贪心算法。
如果要用最少的步骤把原数列改成从 \(1\) 到 \(n\) 的有序数列,即:使数列里每个数与目标数列的差之和最小。所以可得:
-
将原数列排序
-
计算每个数与目标数列的差值
-
累加,输出答案
最终得到的答案是:
\[\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 迁移至博客园。
本文采用 「CC-BY-NC 4.0」 创作共享协议,转载请注明作者及出处,禁止商业使用。
作者:Jerrycyx,原文链接:https://www.cnblogs.com/jerrycyx/p/19065117

浙公网安备 33010602011771号