pat甲级 1067 Sort with Swap(0, i) (25 分) (思维)

题目链接:传送门

思路:自己的瞎搞的假算法得了8分。。(这里就不贴了),然后看了题解,对于序列中的数字a[i],必定有数占用了他原来的位置,存在一条占用链:如:i 占用 j的位置,j占用k的位置,k占用i的位置。(占用链一定是一个环,应该可以证明)
具体思路就是:因为只能用0交换,如果0不在自己的位置(则0占据了别的数的位置),先通过交换使它在0位置(与它交换的全部的数字都会回到自己的位置),然后看第i个数,是否在自己的位置,如果不在,就把他和0进行交换(让0占据他的位置),然后在下一轮交换进行交换后,会到达合适位置。每轮交换次数是num+1,num是本轮正确排序的数字。(这应该能最小的交换次数)

#include <bits/stdc++.h>

using namespace std;
 
const int maxn = 1e5 + 5;

int a[maxn] , vis[maxn]; 
 
int main() {
	int n;
	ios::sync_with_stdio(0);
	cin >> n;
	int cnt = 0 , ans = 0;
	for(int i = 0 ; i < n ; i++) {
		cin >> a[i];
		vis[a[i]] = i;
	}
	int i = 1;
	while(i < n) {
		while(vis[0] != 0) {
			int t = vis[0];
			//swap(a[vis[t]] , a[vis[0]]);
			swap(vis[t] , vis[0]);
			ans++;
		}
		if(vis[i] != i) {
			ans++;
			swap(vis[i] , vis[0]);
			//swap(a[vis[i]] , a[vis[0]]);
		}
		i++;
	}
	cout << ans << "\n"; 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39475280/article/details/103065846