题意:
只能用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; }