【排序算法】使数组有序的最少移动步数

给出n个元素,不一定有序,分别按以下要求进行排序:
(1)每次只能交换两个元素;
题目来源:CTU Open Contest 2017 H题
(2)每次只能把元素移到第一个位置;
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=6006
AC代码:
分别求出在这两种情况下移动的最少次数
第一种情况:原数组逐个与有序序列比对,如果不在自己本该的在的位置上,就交换一次;

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		int a[n];
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
		}
		
		int sum=0,ans;
		for(int i=1;i<=n;i++)
		{
			if(i!=a[i])
			{
				int temp=i;
				ans=0;
				while(i!=a[temp])//逐步交换
				{
					int t=temp;
					temp=a[temp];
					a[t]=t;
					ans++;
				}
				a[temp]=temp;
				sum+=ans;
			}
		}
		printf("%d\n",sum);
	}
	return 0;
}

第二种情况:拿一个已经排好序的数组从后面开始比较,有序的直接跳过,记录无序的数量,即为要移动的;

#include<bits/stdc++.h>
using namespace std;
int main()
{
   int t;
   scanf("%d",&t);
   while(t--)
   {
   	int n;
   	scanf("%d",&n);
   	int a[n],b[n];
   	for(int i=0;i<n;i++)
   	{
   		scanf("%d",&a[i]);
   		b[i]=a[i];
   	}
   	
   	sort(b,b+n);//b数组已经排好序,作为参照;
   	int pa,pb,ans=0;
   	for(pa=n-1,pb=n-1;pa>=0;)//从后面开始比对,已经有序的就不要管了
   	{
   		if(a[pa]==b[pb])
   		{
   			pa--;
   			pb--;
   		}
   		else if(a[pa]!=b[pb])
   		{
   			ans++;
   			pa--;
   		}
   		if(pa<0)
   		break;
   	}
   	printf("%d\n",ans);
   }
   return 0;
} 

因为见过几次这种类型的题,也走过弯路,所以小小总结一下,后面再又遇到,再加进来;

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值