题目描述
初始给你一个排列p[i],你可以执行以下操作任意多次。
选择一个i,交换p[i]和p[i+1]的值(其实就是交换排列当中两个相邻的元素)。
我们现在希望对于任意的i满足p[i]不等于i,求最少需要执行的操作次数。
输入
输入文件A.in。
第一行一个整数n。
第二行n个整数,其中第i个整数表示p[i]。
输出
输出文件A.out
一行一个整数表示最少的操作次数。
样例输入
5
1 4 3 5 2
样例输出
2
【样例输入2】
2
1 2
【样例输出2】
1
【样例输入3】
9
1 2 4 9 5 8 7 3 6
【样例输出3】
3
【数据范围】
对于 30% 数据 $ n le 10 $
对于 50% 数据 $ n le 10^3 $
对于 100% 数据 $ n le 10^5 $
这道题反正我是感觉我做的挺SB的............一开始写了N个错误的贪心 $ QwQ $ (我也不知道自己在想什么)
反正就是很谜,后来我就 $ xjb $ 乱贪,然后贪过了....大体就是正着扫一遍,遇到 $ i == p_i $ 的就把它和后面的交换
然后反着再扫一遍,就过了......
代码如下:
#include <iostream>
#include <cstdlib>
#include <cstdio>
const int N = 1e5 + 5 ;
int n,v[N];
int ans;
int main(){
scanf("%d" , & n );
for (int i = 1 ; i <= n ; ++ i) scanf("%d" , & v[i]);
for (int i = 1 ; i < n ; ++ i){
if(v[i] == i){
++ ans ;
std::swap( v[i] , v[i + 1] );
}
}
for (int i = n ; i >= 2 ; -- i){
if(v[i] == i){
++ ans ;
std::swap( v[i] , v[i - 1] );
}
}
printf ("%d
" , ans );
return 0;
}