我们称一个长度为n的序列为正则序列,当且仅当该序列是一个由1~n组成的排列,即该序列由n个正整数组成,取值在[1,n]范围,且不存在重复的数,同时正则序列不要求排序
有一天小团得到了一个长度为n的任意序列s,他需要在有限次操作内,将这个序列变成一个正则序列,每次操作他可以任选序列中的一个数字,并将该数字加一或者减一。
请问他最少用多少次操作可以把这个序列变成正则序列?
数据范围:
,
进阶:时间复杂度
,空间复杂度%5C)
我们称一个长度为n的序列为正则序列,当且仅当该序列是一个由1~n组成的排列,即该序列由n个正整数组成,取值在[1,n]范围,且不存在重复的数,同时正则序列不要求排序
有一天小团得到了一个长度为n的任意序列s,他需要在有限次操作内,将这个序列变成一个正则序列,每次操作他可以任选序列中的一个数字,并将该数字加一或者减一。
输入第一行仅包含一个正整数n,表示任意序列的长度。(1<=n<=20000)
输入第二行包含n个整数,表示给出的序列,每个数的绝对值都小于10000。
输出仅包含一个整数,表示最少的操作数量。
5 -1 2 3 10 100
103
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int ans = 0;
int[] a = new int[n + 1];
for (int i = 0; i < n; i++) {
int k = in.nextInt();
if (k < 1) {
ans += 1 - k;
a[1]++;
} else if (k > n) {
ans += k - n;
a[n]++;
} else {
a[k]++;
}
}
int x = 1;
for (int i = 0; i <= n; i++) {
while (a[i] > 1) {
while (a[x] != 0) x++;
ans += Math.abs(i - x);
a[i]--;
a[x]++;
}
}
System.out.println(ans);
}
} import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
scan.nextLine();
String[] arr = scan.nextLine().split(" ");
int[] scores = new int[n];
for(int i = 0;i<n;i++){
scores[i]=Integer.parseInt(arr[i]);
}
int neg = 0;
int negNum = 0;
int pos = 0;
int posNum = 0;
for(int i = 0;i<n;i++){
if(scores[i]<0){
neg+=scores[i];
negNum++;
}else{
pos+=scores[i];
posNum++;
}
}
int negSum = negNum>0 ?negNum*(negNum+1)/2 - neg : 0;
int posSum = posNum>0? Math.abs((posNum)*(2*n-posNum+1)/2 - pos) : 0;
int sum = negSum+ posSum;
System.out.println(sum);
}
}