RDay2-Problem 1 A

本文介绍了一道算法题目,目标是找到将一个给定的排列调整为正确顺序所需的最少交换次数。通过两次扫描算法,先从左到右再从右到左,每次遇到位置与数值相等的元素进行交换并计数,最终输出总交换次数。

题目描述
初始给你一个排列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\n" , ans );
    return 0;
}

转载于:https://www.cnblogs.com/Equinox-Flower/p/9896914.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值