链接:https://ac.nowcoder.com/acm/contest/5773/E
来源:牛客网
牛客幼儿园的小朋友课间操时间需要按照学号从小到大排队,但是他们太小了只能站成一列顺序却不对,现在幼儿园的阿姨需要帮忙交换小朋友的位置让他们最终有序,阿姨希望能尽快完成交换操作,问最少需要交换多少次,才能使得小朋友们从小到大排好。
注意:每个小朋友的学号不同,但是未必连续,因为可能有小朋友请假了没有来。
输入描述:
第一行一个整数 N。
接下来 N 行每行一个整数,为小朋友们的队列。
输出描述:
一个整数表示小朋友们的最小交换次数。
示例1
输入
3 2 1 3
输出
1
备注:
N≤100000,其他整数均≤109N\leq100000,其他整数均\leq 10^{9}N≤100000,其他整数均≤109
思路:这题挺有意思的,因为线代学多了我一开始以为是逆序数。成一个环需要交换的次数就减一,因为此环中有一次交换可以让两个数恢复原位,不需要换和两个互换的也可以借助map看成环。
#include <bits/stdc++.h> using namespace std; #define ll long long const int mod=1e9+7; const int N=1e5; int a[N],b[N],flag[N]; int n; int find_min(){ int num=0; for(int i=0;i<n;i++) b[i]=a[i]; sort(b,b+n); map<int,int>m; for(int i=0;i<n;i++) m[b[i]]=i; for(int i=0;i<n;i++){ if(!flag[i]){ int j=i; while(!flag[j]){ flag[j]=true; j=m[a[j]]; } num++; } } return n-num; } int main(){ cin>>n; for(int i=0;i<n;i++) cin>>a[i]; int ans=find_min(); cout<<ans<<endl; return 0; }