我们称一个长度为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.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine().trim());
String[] strSeq = br.readLine().trim().split(" ");
int[] seq = new int[n];
for(int i = 0; i < n; i++) seq[i] = Integer.parseInt(strSeq[i]);
Arrays.sort(seq);
int modifyTimes = 0;
for(int i = 1; i <= n; i++) modifyTimes += Math.abs(seq[i - 1] - i);
System.out.println(modifyTimes);
}
} #include <iostream>
#include <vector>
#include <algorithm>
#include <stdlib.h>
using namespace std;
int main() {
int n, ans = 0;;
cin >> n;
vector<int>que(n, 0);
for (int i = 0; i < n; ++i) cin >> que[i];
sort(que.begin(), que.end());
for (int i = 1; i <= n; ++i) {
ans += abs(i - que[i - 1]);
}
cout << ans;
return 0;
} 刚开始没看出来这道题目考的是什么?其实就是贪心。我们要让每个数字移动的步数最少,或者说让每个数字找距离下标[1,n]最近的位置填充。当时思路是有了,但是我一直没有排序,所以测试样例通过了,然后整体运行通不过,百思不得解。后来发现先排序,然后将所有数字按照[1,n]的坑位从小到大填。这样就能保证距离最小,整体思路是对的,还要保证数组整体有序。
保证最后所有的数值取值在[1,n],先排序,然后从左到右遍历,这样就能取得最小步数。
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n];
for(int i=0;i<n;i++){
arr[i] = sc.nextInt();
}
Arrays.sort(arr);
int res = 0;
for(int j=1;j<=n;j++){
res += Math.abs(arr[j-1] - j);
}
System.out.println(res);
}
}以上,下课
n = int(input()) a = list(map(int, input().strip().split())) a.sort() sum = 0 for i in range(1,n+1): sum += abs(i-a[i-1]) print(sum)
import java.util.*;
public class Main {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] nums = new int[n];
int ans = 0;
for(int i = 0;i < n;i++)
nums[i] = sc.nextInt();
Arrays.sort(nums);
for(int i = 0;i < n;i++){
ans += Math.abs(i + 1 - nums[i]);
}
System.out.println(ans);
}
} #include<iostream>
using namespace std;
const int N = 2e4 + 5;
int n;
int a[N], tmp[N];
int main()
{
cin >> n;
int _max = 0;
for (int i = 1; i <= n; i ++ ) {
cin >> a[i];
tmp[a[i] + 10000]++;
_max = max(_max, a[i] + 10000);
}
int idx = 0;
for (int i = 0; i <= _max; i ++ ) {
if (!tmp[i]) {
continue;
}
while (tmp[i] -- > 0) {
a[idx ++ ] = i - 10000;
}
}
int ans = 0;
for (int i = 1; i <= n; i ++ ) {
ans += abs(i - a[i - 1]);
}
cout << ans << endl;
return 0;
} #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
vector<int> nums(n);
for(int i = 0; i < n; i++)
cin >> nums[i];
int count = 0;
sort(nums.begin(), nums.end());
for(int i = 0; i < n; i++)
{
if(nums[i] >= 1 && nums[i] <= n)
swap(nums[i], nums[nums[i] - 1]);
}
for(int i = 1; i <= n; i++)
{
if(i != nums[i - 1])
count += abs(nums[i - 1] - i);
}
cout << count << endl;
return 0;
} import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int minCount = new Main().minCount();
System.out.println(minCount);
}
public int minCount(){
Scanner scanner = new Scanner(System.in);
int n=scanner.nextInt();
int[] arr=new int[n];
for(int i=0;i<n;i++)
arr[i]=scanner.nextInt();
Arrays.sort(arr);
int res=0;
for(int i=0;i<n;i++){
res+=Math.abs(arr[i]-(i+1));
}
return res;
}
} #include<iostream>
using namespace std;
int main(){
int n;
cin >> n;
int b[20001] = {0};
for (int i = 0, num; i < n; i++) {
cin >> num;
b[num + 10000]++;
}
int ans = 0;
for (int num = 0, j = 1; num < 20001 && j <= n; num++) {
while (b[num]--) {
ans += abs(j++ - num + 10000);
}
}
cout << ans;
return 0;
}
package main
import (
"fmt"
"sort"
)
func S(nums []int)int{
sort.Ints(nums)
res:=0
n:=len(nums)
var less,more []int
myMap:=make(map[int]int,n)
for i:=0;i<n;i++ { //把随意序列存进map并记录有多少个重复
myMap[nums[i]] += 1
}
for i:=1;i<=len(nums);i++{ //循环正则序列的值,与随意序列比较有无多或少元素,多存进more,少存进less
v,ok:=myMap[i]
if nums[i-1]<1||nums[i-1]>=n+1{ //注意把超过n范围的元素加入more
more=append(more,nums[i-1])
}
if ok{
if v>1{
add(&more,v-1,i)
continue
}
continue
}
less=append(less,i)
}
for i:=len(more)-1;i>=0;i--{ //此时more和less已经排序浩,长度相等,逐个相减累加和,就是结果
if more[i]>less[i]{
res+=more[i]-less[i]
}else{
res+=less[i]-more[i]
}
}
return res
}
func add(a *[]int, b,c int){
for i:=1;i<=b;i++{
*a=append(*a,c)
}
}
func main(){
var n int
fmt.Scan(&n)
nums:=make([]int,n)
for i:=0;i<n;i++{
fmt.Scan(&nums[i])
}
res:=S(nums)
fmt.Println(res)
}
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int[] arr1=new int[n];
int[] arr2=new int[n];
for (int i = 0; i < n; i++) {
arr1[i]=i+1;
arr2[i]=sc.nextInt();
}
Arrays.sort(arr2);
int sum=0;
for (int i = 0; i < n; i++) {
arr1[i]=Math.abs(arr1[i]-arr2[i]);
sum+=arr1[i];
}
System.out.println(sum);
}
} import java.util.*;
public class Main{
public static void main(String[] args){
Scanner s = new Scanner(System.in);
int n = s.nextInt();
int[] arr = new int[n];
int res = 0;
for(int i = 0;i<n;i++){
arr[i] = s.nextInt();
}
Arrays.sort(arr);
while(arr[0] < 1){
arr[0]++;
res++;
}
for(int i = 1;i<n;i++){
while(arr[i] <= arr[i-1]){
arr[i]++;
res++;
}
}
System.out.println(res);
}
} #include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
int t = 0;
int count = 0;
vector<int> hash(n + 1,0);
for (int i = 0; i < n; i++) {
cin >> t;
if (t >= 1 && t <= n) {
hash[t]++;
}
else if (t < 1) {
count = count + 1 - t;
hash[1]++;
}
else if (t > n) {
count = count + t - n;
hash[n]++;
}
}
int sum = 0;
for(int i=1;i<=n;i++) {
sum = sum + hash[i] * i;
}
count = count + (1+n)*n/2 - sum;
cout << count ;
} 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.Scanner;
import java.lang.Math;
// 贪心算法:对序列 s 进行排序,第 i 位通过加减乘除变成 i
// 优化:采用桶排序
public class Main {
public static void main(String[] args) {
// value 映射到 value+10000 上
int[] buckets = new int[20001];
// 输入数组,放入桶中
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
while (n-- > 0) {
++buckets[scanner.nextInt()+10000];
}
// 第 i 位通过加减乘除变成 i
int result = 0, i = 1;
for (int j = 0; j <= 20000; ++j) {
while (buckets[j]-- > 0) {
result += Math.abs((j-10000) - (i++));
}
}
System.out.println(result);
}
}