南邮 OJ 1736 排序问题

来源:互联网 发布:wow7.0采集数据库 编辑:程序博客网 时间:2024/05/14 10:07

排序问题

时间限制(普通/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 1001int 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);}}


0 0
原创粉丝点击