您的位置:首页 > 其它

南邮 OJ 1736 排序问题

2015-08-06 11:10 246 查看


排序问题

时间限制(普通/Java) : 1000 MS/ 3000 MS 运行内存限制 : 65536 KByte

总提交 : 37 测试通过 : 18

比赛描述

排序是一种很频繁的计算任务。现在考虑最多只有三值的排序问题。一个实际的例子是,当我们给某项竞赛的优胜者按金银铜牌排序的时候。在这个任务中可能的值只有三种1,2和3。我们用交换的方法把他排成升序的。
写一个程序计算出,给定的一个1,2,3组成的数字序列,排成升序所需的最少交换次数。

输入

多组数据
第一行:
奖牌个数N (1 <= N <= 1000)
第 2行到第N+1行:
每行一个数字,表示奖牌。共N行。(1..3)

输出

共一行,一个数字。表示排成升序所需的最少交换次数。

样例输入

9

2

2

1

3

3

3

2

3

1

样例输出

4

提示

undefined

题目来源

ym

// 设 cAB 为在A位置上的B的数目,则答案为:
// c21 + c31 + (c21 > c12 ? c23 + c21 - c12 : c32 + c12 - c21)
// 或者 c12 + c13 + max(c23,c32)

// 1-1、2-2、3-3的不交换(一轮换),1-2和2-1,1-3和3-1,2-3和3-2配对成二轮换,
// 剩下的形成1-2-3或1-3-2的三轮换。最后的交换次数是二轮换的数量加上三轮换的数量乘以二。
// 用公式表示的话就是:
// min(c12,c21) + min(c13,c31) + min(c23,c32) + |c12 - c21| * 2

#include<iostream>
using namespace std;

#define MAX_N 1001
int a[MAX_N];

int main(){
int n, i, count1, count2;
int c12, c13, c21, c23, c31, c32;
while(scanf("%d", &n) == 1){
count1 = count2 = 0;
c12 = c13 = c21 = c23 = c31 = c32 = 0;
for(i = 0; i < n; ++i){
scanf("%d", a + i);
if(a[i] == 1){
count1++;
}else if(a[i] == 2){
count2++;
}
}
for(i = 0; i < count1; ++i){
if(a[i] == 2){
c12++;
}else if(a[i] == 3){
c13++;
}
}
for(i = count1; i < count1 + count2; ++i){
if(a[i] == 1){
c21++;
}else if(a[i] == 3){
c23++;
}
}
for(i = count1 + count2; i < n; ++i){
if(a[i] == 1){
c31++;
}else if(a[i] == 2){
c32++;
}
}
int temp = c12 - c21;
if(temp < 0){
temp = -temp;
}
printf("%d\n",  min(c12,c21) + min(c13,c31) + min(c23,c32) + temp * 2);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: