这个题可以用暴力来做,做法是从前往后遍历,因为保证1-N的数据,如果排好序那么所有的下标对应都是该数字(下标从1开始),那么遍历到哪位如不符,就往后找符合的那一位。
第二个做法稍微优化了一下,所有互相交换的元素形成一个环,一次性完成一个环的交换
下面Java描述暴力做法,Cpp描述图环做法
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 10010;
int n;
int b[N];
bool st[N];
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ) scanf("%d", &b[i]);
int cnt = 0;
for (int i = 1; i <= n; i ++ )
if (!st[i])
{
cnt ++ ;
for (int j = i; !st[j]; j = b[j])
st[j] = true;
}
printf("%d\n", n - cnt);
return 0;
}
作者:yxc
链接:https://www.acwing.com/activity/content/code/content/174698/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter pw = new PrintWriter(System.out);
static int N = 10010, n;
static int a[] = new int[N];
public static void main(String[] args) throws Exception {
String s[] = br.readLine().split(" ");
n = Integer.parseInt(s[0]);
s = br.readLine().split(" ");
for (int i = 1; i <= n; i++) a[i] = Integer.parseInt(s[i - 1]);
if (n == 1) { //特判
pw.print(1);
pw.flush();
pw.close();
br.close();
System.exit(0);
}
int res = 0;
for (int i = 1; i <= n; i++) {
if (a[i] != i) {
for (int j = i + 1; j <= n; j++) {
if (a[j] == i) {
int temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
res++;
}
}
pw.print(res);
pw.flush();
pw.close();
br.close();
}
}