题意:
只能用0跟另一个交换,求最少交换多少次,可以让数列变为连续的
分析:
贪心。大致思想是交换0的下标和0下标的下标进行交换(swap(a[0],a[a[0]),但是需要注意有可能a[0]==0,但是还是没能将序列变为连续的,这时候需要从头往后扫,扫到第一个下标与数不相等的,交换,并加下这个数(如果下次再碰到a[0]==0,但是序列没变成连续的,则从这个数开始往后扫,节省时间)再继续。详细看代码
coding:
#define debug
//#define opentext;
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef string String;
typedef pair<int, int> PII;
const int maxn = 1e8;
const int INF = 0x3f3f3f3f;
const int inf = 0x7fffffff;
const int mod = 1e9 + 7;
const int MOD = 10007;
//------------
//define
int a[maxn];
int cnt,Zero=0,ans,indexx;
void solve() {
int n;
cin>>n;
for(int i=0;i<n;i++){
int tmp;
cin>>tmp;
if(tmp!=i){
cnt++;
}
a[tmp]=i;
}
while(cnt>1){//交换一次实际上影响到的是2个位子,所以当cnt==1的时候,实际上已经回复原状
while(Zero!=a[Zero]){
swap(a[Zero],a[a[Zero]]);
cnt--;
ans++;
}
if(cnt!=0){
//防超时
for(int i=indexx;i<n;i++){
if(i!=a[i]){
swap(a[Zero],a[i]);
ans++;
indexx=i;
break;
}
}
continue;
}
}
cout<<ans<<endl;
}
int main() {
ios_base::sync_with_stdio(0);
#ifdef debug
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
cin.tie(0);
cout.tie(0);
solve();
//-------------------------------------
#ifdef opentext
fclose(stdin);
fclose(stdout);
system("out.txt");
#endif
//-------------------------------------
return 0;
return 0;
}