给出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;
}
因为见过几次这种类型的题,也走过弯路,所以小小总结一下,后面再又遇到,再加进来;