Problem C: 2.1.3 Sorting a Three-Valued Sequence 三值的排序
Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 13 Solved: 9
[Submit][Status][Web Board]
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
2
2
1
3
3
3
2
3
1
Sample Output
4
解题思想:
先检查1,能放回原位就放回,检查两遍保证1都放好,再检查2与3,还比较简单
二维数组a[][]按1 2 3的数量分开,第一行共有c1个位置...排好序后第一行全是1,第二行全是2...
将1归位:遍历第一行将第一行为2且第二行为1,或者将第一行为3且第三行为1的交换,此时每交换1次有两个数归位;
扫描第二、三行,使得二三行有1的,交换,使1归位,此时每交换1次只有1归位。
将2归位:剩下的就是将第二行的3与第三行的2交换,全部归位。
#include <iostream>
using namespace std;int a[1005][1005];
int b[1005];
int main()
{
int i,j,k;
int c1=0,c2=0,c3=0,ct=0,n;
cin>>n;
for(i=1;i<=n;i++) //统计1 2 3的个数,并把数存到b[]中
{
cin>>b[i];
if(b[i]==1)
c1++;
if(b[i]==2)
c2++;
if(b[i]==3)
c3++;
}
for(i=1;i<=c1;i++) //二维数组a[][]按1 2 3的数量分开,第一行共有c1个位置...排好序后第一行全是1,第二行全是2...
a[1][i]=b[i];
for(i=c1+1;i<=c1+c2;i++)
a[2][i-c1]=b[i];
for(i=c1+c2+1;i<=n;i++)
a[3][i-c1-c2]=b[i];
for(j=1;j<=c1;j++) //将1归位:遍历第一行将第一行为2且第二行为1,或者将第一行为3且第三行为1的交换,此时交换1次有两个数归位
{
if(a[1][j]==2)
{
for(i=1;i<=c2;i++)
{
if(a[2][i]==1)
{
b[0]=a[1][j];
a[1][j]=a[2][i];
a[2][i]=b[0];
ct++;
break;
}
}
}
if(a[1][j]==3)
{
for(i=1;i<=c3;i++)
{
if(a[3][i]==1)
{
b[0]=a[1][j];
a[1][j]=a[3][i];
a[3][i]=b[0];
ct++;
break;
}
}
}
}
for(i=1;i<=c2;i++) //扫描第二、三行,使得二三行有一的,交换,使一归位,此时只有一归位。
{ //至此一全部归位,剩下的就是将第二行的3与第三行的2交换,全部归位
if(a[2][i]==1)
{
for(j=1;j<=c1;j++)
{
if(a[1][j]!=1)
{
b[0]=a[1][j];
a[1][j]=a[2][i];
a[2][i]=b[0];
ct++;
break;
}
}
}
}
for(i=1;i<=c3;i++)
{
if(a[3][i]==1)
{
for(j=1;j<=c1;j++)
{
if(a[1][j]!=1)
{
b[0]=a[1][j];
a[1][j]=a[3][i];
a[3][i]=b[0];
ct++;
break;
}
}
}
}
for(i=1;i<=c2;i++)
{
if(a[2][i]==3)
{
for(j=1;j<=c3;j++)
{
if(a[3][j]==2)
{
b[0]=a[3][j];
a[3][j]=a[2][i];
a[2][i]=b[0];
ct++;
break;
}
}
}
}
cout<<ct<<endl;
return 0;
}