[USACO 2.1.3] Sorting a Three-Valued Sequence

本文介绍了一种针对仅有三个不同值(1、2、3)的序列进行排序的算法。该算法采用基数排序并结合贪心策略来计算将序列转换为升序所需的最小交换次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[题目描述]

Sorting a Three-Valued Sequence

三值的排序
IOI'96 - Day 2

排序是一种很频繁的计算任务。现在考虑最多只有三值的排序问题。一个实际的例子是,当我们给某项竞赛的优胜者按金银铜牌序的时候。

在这个任务中可能的值只有三种1,2和3。我们用交换的方法把他排成升序的。

写一个程序计算出,给定的一个1,2,3组成的数字序列,排成升序所需的最少交换次数。

PROGRAM NAME: sort3

INPUT FORMAT

Line 1:

N (1 <= N <= 1000)

Lines 2-N+1:

每行一个数字,共N行。(1..3)

SAMPLE INPUT (file sort3.in)

9
2
2
1
3
3
3
2
3
1

OUTPUT FORMAT

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

SAMPLE OUTPUT (file sort3.out)

4



[解题思路]
由于需要排序的值只有1~3,所以可以边读入边基数排序,然后O(N)的预处理出一个数组t[i,j],i,j∈[1,3],表示在i应在的区间里的j的个数。
所以贪心的想法就是,先交换一次就能两两复原的数对,所以交换1中的2与2中的1,1中的3,与3中的1......这样,都只需交换一次。
而剩下的的在1中的2与1中的3都不能直接交换了,必须借助另一个区间的值,所以要交换两次,于是累计答案就行了。

[Code]
{
ID: zane2951
PROG: sort3
LANG: PASCAL
}

program sort3;
var
   a:array[0..1111] of longint;
   c:array[0..4] of longint;
   t:array[0..4,0..4] of longint;
   n,i,ans,ce:longint;

//-----------min-----------
function min(a,b:longint):longint;
begin
   if a<b then exit(a) else exit(b);
end;

//----------main-----------
begin
   assign(input,'sort3.in'); reset(input);
   assign(output,'sort3.out'); rewrite(output);
   readln(n);
   for i:=1 to n do begin readln(a[i]); inc(c[a[i]]); end;
   for i:=1 to c[1] do inc(t[1,a[i]]);
   for i:=c[1]+1 to c[1]+c[2] do inc(t[2,a[i]]);
   for i:=c[1]+c[2]+1 to n do inc(t[3,a[i]]);
   ans:=0;
   //-------swap 1 and 2--------
   ce:=min(t[1,2],t[2,1]);
   ans:=ans+ce;
   t[1,2]:=t[1,2]-ce; t[2,1]:=t[2,1]-ce;
   //-------swap 1 and 3--------
   ce:=min(t[1,3],t[3,1]);
   ans:=ans+ce;
   t[1,3]:=t[1,3]-ce; t[3,1]:=t[3,1]-ce;
   //-------swap 2 and 3--------
   ce:=min(t[2,3],t[3,2]);
   ans:=ans+ce;
   t[2,3]:=t[2,3]-ce; t[3,2]:=t[3,2]-ce;
   //-------swap 1 and 2 and 3--------
   ans:=ans+t[1,2]<<1+t[1,3]<<1;
   writeln(ans);
   close(input); close(output);
end.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值