A1067 Sort with Swap(0, i) (贪心)

题目描述

题目给定一个序列0,1,……,N-1,要求通过两两交换(0和另一个数),使其变为递增序列

题目意思很简单,问题是如何用尽可能最简单的策略来实现。
1.若0在i号位(i≠0),则找到i所在位置,将0与i交换
2.若0在0号位,则找到第一个不在自己位置的数,将0与其交换,这样又回到了1所在的情况,也不会对已经到达自己位置的数字产生影响

以下为算法笔记中的模拟过程和参考代码:
在这里插入图片描述
另外,注意代码中的left变量

#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=100010;
int pos[maxn];

int main(){
	int n,ans = 0;
	scanf("%d", &n);
	int left=n-1,num;//left存放除0以外不在本位上的数
	for(int i=0; i<n; i++){
		scanf("%d", &num);
		pos[num] = i;
		if(num==i&&num!=0)//去除已经在本位上的数
            left--;
	}
	int k=1;//除0以外不在本位上最小的数
	while(left>0){
        if(pos[0] == 0){//0在本位上,寻找第一个当前不在本位上的数与0交换
            while(k<n){
                if(pos[k] != k){
                    swap(pos[0], pos[k]);
                    ans++;
                    break;
                }
                k++;
            }
        }
        while(pos[0] != 0){//0不在本位上,寻找应在0位置上的数字与0交换
            swap(pos[0], pos[pos[0]]);
            ans++;
            left--;
        }
	}
	printf("%d\n", ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43835911/article/details/89434772