CF489A

这题要求用不超过 \(n\) 次的交换将 \(n\) 个整数从小到大排序。很显然,在最坏的情况下,为了满足条件,我们需要使每个数一步到位,即只与要到达的那个位置上的的数交换一次。

那么我们很容易想到用选择排序了。先回顾一下选择排序,核心代码如下:

for(int i=1;i<n;i++)
	for(int j=i+1;j<=n;j++)
		if(a[i]>a[j])
			swap(a[i],a[j]);

我们很容易发现:当到达第 \(i\) 个位置时,前面的 \(i-1\) 个数已经有序了,因此我们只需求出 $ \min(a_{i+1},a_{i+2},\cdots,a_n)$ 的位置,将此位置上的数与 \(a_i\) 交换,记录答案即可。特别地,若两数的位置相同,则说明 \(a_i\) 的位置是正确的,没有必要交换。

实现时注意数组下标从 \(0\) 开始,代码如下:

#include <iostream>
#include <cstdio>
using namespace std;
int a[10001],n;
int ans,x[10001],y[10001];
int main()
{
	cin>>n;
	for(int i=0;i<n;i++)
		cin>>a[i];
	for(int i=0;i<n-1;i++)
	{
		int mi=a[i],id=i;
		for(int j=i+1;j<n;j++)
			if(a[j]<mi)
			{
				mi=a[j];
				id=j;
			}
		if(id!=i)
		{
			swap(a[i],a[id]);
			ans++;
			x[ans]=i;
			y[ans]=id;
		}
	}
	cout<<ans<<endl;
	for(int i=1;i<=ans;i++)
		cout<<x[i]<<' '<<y[i]<<endl;
	return 0;
}
posted @ 2024-01-20 17:43  liyilang2021  阅读(3)  评论(0编辑  收藏  举报