这道题是一个错排问题。
由于要求调换的次数最少,容易发现,输出的答案次数只可能是0、1、2中的一个。
若一开始所有元素就已经都在对应的位置上,则输出答案为0;
若有元素不在对应的位置上,那么就要看这个数列中有几个错排的子段(遇到处在对应位置上的元素,要断开并从其之后重新计数,具体见代码,我用了flag进行处理)。
如果这样的子段恰好有1个,那么输出答案为1;
如果这样的子段有大于等于2个,那么我们可以发现,只需进行两次调换,就能够实现将所有元素换到对应的位置上,输出答案为2。
AC代码:
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int t,n;
cin>>t;
while(t--)
{
cin>>n;
int a,flag=1,cnt=0;
for(int i=1;i<=n;i++)
{
cin>>a;
if(a!=i&&flag==1)
{
cnt++;
flag=0;
}
if(a==i)
flag=1;
}
if(cnt==0)
cout<<"0"<<endl;
else if(cnt==1)
cout<<"1"<<endl;
else
cout<<"2"<<endl;
}
return 0;
}