20210415——J题
游戏规则
总计循环n次,每次循环先输入一个正整数k(代表接下来输入的数列的长度)
随后输入k个数
问题:需要交换多少次才能将这k个数正序排放
#include<iostream>
#include<cstdio>
using namespace std;
const int N=1e5+10;
int a[N],A[N];//A数组是为了存储a数组中元素的位置
int main()
{
int n,k;
cin >> n;
while(n--)
{
int ans=0;
cin >> k;
for(int i =1;i<=k;i++) //将数组存储进来 下标从1开始有利于后续的计算
{
scanf("%d",&a[i]);
A[a[i]]=i; // 同时将a[i]的位置存储下来
}
// 交换开始
for(int j = 1;j<=k;j++)//交换的最大次数不会超过k次
{
if(a[j]!=j)
{
ans++;
swap(a[j],a[A[j]]);//交换本来应该在这个位置的数字与现在在这个位置的数字的位置
swap(A[j],A[a[A[j]]]);
//同时将A数组中上述 元素的调动,将其元素在A中储存的位置也进行更换
}
}
cout << ans <<endl;
}
return 0;
}
图解
小插曲:让k个数回归自己的位置只需操作k次
唯一可以减少次数的特殊条件是
更换的双方的位置恰为双方所需的位置,例如 2 1 4 3 这种特殊情况,此种情况只需要更换2次
故代码 交换部分最多只需循环k次