Sorting a Three-Valued Sequence
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu
Description
排序是一种很频繁的计算任务。现在考虑最多只有三值的排序问题。一个实际的例子是,当我们给某项竞赛的优胜者按金银铜牌序的时候。 在这个任务中可能的值只有三种1,2和3。我们用交换的方法把他排成升序的。 写一个程序计算出,给定的一个1,2,3组成的数字序列,排成升序所需的最少交换次数。
Input
Line 1: N (1 <= N <= 1000) Lines 2-N+1: 每行一个数字,共N行。(1..3)
Output
共一行,一个数字。表示排成升序所需的最少交换次数。
Sample Input
9 2 2 1 3 3 3 2 3 1
Sample Output
4
对于由“1 2 3”这样的数组成的序列只有两种结果,一种是交换一次,一种是交换两次。分别为 1 3 2 交换2与3: 3 1 2先交换3与1,再换2与3。
题目中给出的序列只由“1 2 3”三个数组成,所以可以将序列划分为1,2,3的3个区域,然后分两步走。将序列划分为若干组“1 2 3”序列,第一步,将通过一次便可交换到正确位置的数进行交换。第二步,第一步进行完后会形成n组“1 2 3”序列,再采用上一段提到的第二种交换。结束。
本题要点:将原问题分解成子问题(即题中序列是由“1 2 3”这样的数列组合而成),分析子问题的本质
。
AC代码:
#include <iostream>
#include<stdio.h>
using namespace std;
int main()
{
int con[1009];
int n,t,i,p,j,ans;
int a1,b1,c1,a2,b2,c2,a3,b3,c3;
int a,b,c,q,w,e,y;
while(scanf("%d",&n)!=EOF)
{
ans=0;
a1=a2=a3=b1=b2=b3=c1=c2=c3=0;
a=b=c=0;
for(i=1;i<=n;i++)
{
scanf("%d",&con[i]);
if(con[i]==1)
a++;
if(con[i]==2)
b++;
if(con[i]==3)
c++;
}
for(i=1;i<=a;i++)
if(con[i]==1)
a1++;
else if(con[i]==2)
b1++;
else if(con[i]==3)
c1++;
for(i=a+1;i<=a+b;i++)
if(con[i]==1)
a2++;
else if(con[i]==2)
b2++;
else if(con[i]==3)
c2++;
for(i=a+b+1;i<=a+b+c;i++)
if(con[i]==1)
a3++;
else if(con[i]==2)
b3++;
else if(con[i]==3)
c3++;
q=w=e=0;
while(1)
{
if(b1>0&&a2>0)
{
ans++;
a2--;
b1--;
}
else
q=1;
if(c1>0&&a3>0)
{
ans++;
a3--;
c1--;
}
else
w=1;
if(c2>0&&b3>0)
{
ans++;
c2--;
b3--;
}
else
e=1;
if(q==1&&w==1&&e==1)
break;
}
y=b1+c1+a2+c2+a3+b3;
ans=ans+y/3*2;
printf("%d\n",ans);
}
return 0;
}