三值的排序 Sorting a Three-Valued Sequence(洛谷 P1459)
程序员文章站
2024-03-19 09:28:58
...
三值的排序 Sorting a Three-Valued Sequence
题目描述
排序是一种很频繁的计算任务。现在考虑最多只有三值的排序问题。一个实际的例子是,当我们给某项竞赛的优胜者按金银铜牌排序的时候。在这个任务中可能的值只有三种1,2和3。我们用交换的方法把他排成升序的。
写一个程序计算出,给定的一个1,2,3组成的数字序列,排成升序所需的最少交换次数
输入格式
第一行:
奖牌个数N (1 <= N <= 1000)
第 2行到第N+1行:
每行一个数字,表示奖牌。共N行。(1…3)
输出格式
共一行,一个数字。表示排成升序所需的最少交换次数。
输入 #1
9
2
2
1
3
3
3
2
3
1
输出 #1
4
纯思维题;我们要知道一个未排序的序列要跟排序后的序列比,在相同的位置有不同的数,如果未排序a[1]=2,a[5]=1;而排序后a[1]=1,a[5]=2,那么这两个数只要交换一次就行;我们只要统计这种的数字就可以;然后还会有几个数字剩余,这种数字都是3的倍数,3个数只要交换2次,最后统计这种数字个数除以3就行;
代码:
#include<bits/stdc++.h>
using namespace std;
int an[1010];
int a[1010];
int s1,s2,s3;
int vis[1010];
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(a[i]==1) s1++;
if(a[i]==2) s2++;
if(a[i]==3) s3++;
an[i]=a[i];
}
sort(a+1,a+n+1);
int ans=0;
for(int i=1;i<=n;i++){
if(an[i]==a[i]){
vis[i]=1;
continue;
}
if(vis[i]) continue;
if(i>=1&&i<=s1){
if(an[i]==2){
for(int j=s1+1;j<=s1+s2;j++){
if(vis[j]) continue;
if(an[j]==1){
ans++;
vis[j]=1;
vis[i]=1;
break;
}
}
}
else if(an[i]==3){
for(int j=s1+s2+1;j<=n;j++){
if(vis[j]) continue;
if(an[j]==1){
ans++;
vis[j]=1;
vis[i]=1;
break;
}
}
}
}
else if(i>=s1+1&&i<=s1+s2){
if(an[i]==3){
for(int j=s1+s2+1;j<=n;j++){
if(vis[j]) continue;
if(an[j]==2){
ans++;
vis[j]=1;
vis[i]=1;
break;
}
}
}
}
}
int ok=0;
for(int i=1;i<=n;i++){
if(vis[i]) continue;
ans++;
ok++;
}
if(ok) cout<<ans-ok/3<<endl;
else cout<<ans<<endl;
return 0;
}