我们称一个长度为n的序列为正则序列,当且仅当该序列是一个由1~n组成的排列,即该序列由n个正整数组成,取值在[1,n]范围,且不存在重复的数,同时正则序列不要求排序
有一天小团得到了一个长度为n的任意序列s,他需要在有限次操作内,将这个序列变成一个正则序列,每次操作他可以任选序列中的一个数字,并将该数字加一或者减一。
请问他最少用多少次操作可以把这个序列变成正则序列?
数据范围:
,
进阶:时间复杂度
,空间复杂度![](https://www.nowcoder.com/equation?tex=O(n)%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); } }