P1459 三值的排序 Sorting a Three-Valued Sequence
P1459 三值的排序 Sorting a Three-Valued Sequence
题目描述
排序是一种很频繁的计算任务。现在考虑最多只有三值的排序问题。一个实际的例子是,当我们给某项竞赛的优胜者按金银铜牌排序的时候。在这个任务中可能的值只有三种1,2和3。我们用交换的方法把他排成升序的。
写一个程序计算出,给定的一个1,2,3组成的数字序列,排成升序所需的最少交换次数
输入输出格式
输入格式:
第一行:
奖牌个数N (1 <= N <= 1000)
第2行到第N+1行:
每行一个数字,表示奖牌。共N行。(1..3)
输出格式:
共一行,一个数字。表示排成升序所需的最少交换次数。
思路解释:由于是对1、2和3进行排序,所以我们要先计算出所给示例中1、2、3的数量,根据不同数的数量我们对于数据进行分区域,然后数据两两交换(同时注意:每3个数通过2次交换就能到达任意位置),最后将所有的交换数相加即得解。
分析:我们以所给数据来进行过程模拟:
输入:2 2 1 3 3 3 2 3 1 输出:4
我们假设1、2、3的个数分别为c1,c2,c3;
开辟二维数组计算有多少的数字不在自己应该所在的位置上:num[][];
假设交换次数为count.
模拟:我们首先输入数据,通过计算,得到:c1=2,c2=3,c3=4。也就是说:数据的前2个(区域1)应该为1,数据的3--5(区域2)应该为2,数据的6--9(区域3)应该为3,我们需要将区域1是2的数字与区域2是1的数字进行交换,将区域1是3的数字与区域3是1的数字进行交换;区域2与区域3同理。(即区域2是1的数字与区域1是2的数字进行交换,区域2是3的数字与区域3是2的数字进行交换)
之后我们可以通过二维数组进行某区域中不同的数的数量的统计,即:输入数据中区域1中有2个2,0个3;区域2中有1个1,2个3;区域3中有1个1,1个2,也就是:
num[1][2]=2,num[1][3]=0;(区域1有2个2,0个3)
num[2][1]=1,num[2][3]=2;(区域2有1个1,2个3)
num[3][1]=1,num[3][2]=1.(区域3有1个1,1个2)
之后我们将区域1的2与区域2的1交换,即:
num[1][2]=1,num[2][1]=0,count+1.
区域2的3与区域3的2交换,即:
num[2][3]=1,num[3][2]=0,count+1
即最终得到:
num[1][2]=1,num[1][3]=0;
num[2][1]=0,num[2][3]=1;
num[3][1]=1,num[3][2]=0,
即区域1 中有1个2,区域2有1个3,区域3有1个1,由于每3个数通过2次交换就能到达任意位置,所以count+2即可,最后输出count=4.
点击查看代码
#include<stdio.h>
int min(int a, int b)
{
if (a < b)
{
return a;
}
else
{
return b;
}
}
int main()
{
int n;
scanf("%d", &n);
int arr[1000];
int c1 = 0, c2 = 0, c3 = 0, c4[4][1000] = { 0 }, count = 0;
for (int i = 1; i <= n; i++)
{
scanf("%d", &arr[i]);
if (arr[i] == 1)
{
c1++;
}
else if (arr[i] == 2)
{
c2++;
}
else
{
c3++;
}
}
for (int i = 1; i <= n; i++)
{
if (i <= c1 && arr[i] != 1)
{
c4[1][arr[i]]++;
}
if (i > c1 && i <= c2 + c1 && arr[i] != 2)
{
c4[2][arr[i]]++;
}
if (i > c2 + c1 && i <= n && arr[i] != 3)
{
c4[3][arr[i]]++;
}
}
for (int i = 1; i <= 3; i++)
{
for (int j = 1; j <= 3; j++)
{
int t = min(c4[i][j], c4[j][i]);
c4[i][j] = c4[i][j] - t;
c4[j][i] = c4[j][i] - t;
count = count + t;
}
}
int tmp = 0;
for (int i = 1; i <= 3; i++)
{
for (int j = 1; j <= 3; j++)
{
if (i != j)
{
tmp = tmp + c4[i][j];
}
}
}
count = count + (tmp * 2 / 3);
printf("%d", count);
return 0;
}