Sorting a Three-Valued Sequence
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sorting a Three-Valued Sequence相关的知识,希望对你有一定的参考价值。
排序是一种很频繁的计算任务。现在考虑最多只有三值的排序问题。一个实际的例子是,当我们给某项竞赛的优胜者按金银铜牌序的时候。 在这个任务中可能的值只有三种1,2和3。我们用交换的方法把他排成升序的。 写一个程序计算出,给定的一个1,2,3组成的数字序列,排成升序所需的最少交换次数。
本以为又是什么高端的数学。虽然是,但是并不会。
所以还是朴实做题。。
把原数组叫做A,升序排序后的数组叫做B。
【B数组就分为了 1 2 3 三个区域】
于是
那么我们的对调就还是分为两类。
1-2 2-3 1-3 直接一次性对调(need 1 ci per this gui)
和 1,2,3之间轮调(needs 2 ci per this gui)
【剩下的一类就是本来就在自己的区域上,并不需要调动】
所以Answer = x + y/3+2 (其中 x 表示用方式一 进行对调的 对数(注意是对数) , y 表示所有数中需要用方式2进行轮调的数字个数)
(又因为 每次对调可以解决3个数的问题 所以共y/3次轮调,但每次又花费次数为2,所以乘以2就是花费了)
代码:
#include <stdio.h> int a[1001]; int compare(int s1,int e1,int num1,int s2,int e2,int num2){ int i,j,sum=0; for(i=s1,j=s2;i<s1+e1 && j<s2+e2;i++,j++){ if(a[i]==num2 || a[j]==num1){ if(a[j]!=num1){ for(;j<s2+e2;j++) if(a[j]==num1) break; } else if(a[i]!=num2){ for(;i<s1+e1;i++) if(a[i]==num2) break; } if(i==s1+e1 || j==s2+e2) break; a[i]^=a[j]; a[j]^=a[i]; a[i]^=a[j]; sum++; } } return sum; } void solve(int n){ int i,sum=0,count=0; int num[3]={0}; for(i=0;i<n;i++) num[a[i]-1]++; sum+=compare(0,num[0],1,num[0],num[1],2); sum+=compare(num[0],num[1],2,num[0]+num[1],num[2],3); sum+=compare(0,num[0],1,num[0]+num[1],num[2],3); for(i=0;i<num[0];i++){ if(a[i]!=1) count++; } for(;i<num[0]+num[1];i++){ if(a[i]!=2) count++; } for(;i<n;i++){ if(a[i]!=3) count++; } sum+=count/3*2; printf(“%d\n”,sum); } int main(){ int n; while(scanf(“%d”,&n)!=EOF){ int i; for(i=0;i<n;i++) scanf(“%d”,&a[i]); solve(n); } return 0; }
以上是关于Sorting a Three-Valued Sequence的主要内容,如果未能解决你的问题,请参考以下文章
Sorting a Three-Valued Sequence
Sorting a Three-Valued Sequence(三值的排序)
[USACO][DAG上的动态规划]Sorting A Three-Valued Sequence