USACO 2.1 Sorting a Three-Valued Sequence

最快的方法当然是O(n)了

先桶排一下,知道多少个1,多少个2,多少个3. 这样我就知道,有多少个2和多少个3在1的位置上~


a[i][j]表示,在有多少个i在j的位置上


那么如果tmp = min(a[i][j]  , a[j][i]), 显然至少要tmp次才可以把他们这一组数组交换位置。


那么就要进行那么几次配对,把可以直接交换位置的全部交换完毕。 这些是不可能有简单的方法来交换的。


为何我在最后直接,再 ans += (b[0][1] + b[0][2]) * 2;;,就得到答案了呢~?


因为,可以把模型抽象成一个图。  从1即将出去的数字的数量,和要进入1的数字数量一定是等价的。 

也就是把1,2,3看成3个顶点。 这3个顶点的入度和出度一定都是一样的。   所以b[0][1] 和b[0][2] 就是从1这个点的出度了。  因为图的特殊性,要不3个都是强联通分量,要不就是连成一个三角形。 所以直接把出度乘以3即可。


/*
TASK:sort3
LANG:C++
*/
#include <stdio.h>
#define min(a, b)	(a)<(b)?(a):(b)
const int max_n = 1000;
int n, ans=0, tmp, i, j, a[max_n],b[3][3]={0}, c[3]={0};
int main()
{
	freopen("sort3.in", "r", stdin);
	freopen("sort3.out", "w", stdout);
	scanf("%d", &n);
	for (i = 0; i != n; ++ i)	
	{
		scanf("%d", &a[i]);
		++ c[--a[i]];
	}
	for (i = 0; i <c[0]; ++ i)	++ b[0][a[i]];
	for (i = c[0] ; i != c[0] + c[1]; ++ i)	++b[1][a[i]];
	for (i = c[0] + c[1] ; i != n; ++ i)	++b[2][a[i]];
	for (i = 0; i != 2;++ i)
		for (j = 1; j != 3; ++ j)
		{
			if (i == j)	continue;;
			tmp = min(b[i][j], b[j][i])	;
			b[i][j] -= tmp;
			b[j][i] -= tmp;
			ans += tmp;
		}
	ans += (b[0][1] + b[0][2]) * 2;
	printf("%d\n",ans);
	return 0;
}



下面试试当成逆序对来解决这个题目?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值