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

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

#include
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
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=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;
} 

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

你可能感兴趣的:(算法)