南京信息工程大学第二届程序设计大赛团队赛:H-重薪排序

题目描述

今年,ThinkSpirit 实验室在 CPC 竞赛上收获颇丰,获得若干金奖、银奖、铜奖。

但是,因为参加了多场比赛,每场比赛的比赛时间不一样,有先后顺序,所以拿回来的奖牌的顺序是按时间顺序排列的,而不是按金银铜奖的顺序排列的。

现在让你帮忙整理奖牌,使得它们按照金银铜奖的顺序重薪排列,即把金奖放在最前面,银奖放在中间,铜奖放在最后面。

值得注意的是,因为奖牌已经摆放好了,所以你只能两两交换其中的奖牌,让它们按照需要的顺序重薪排列,你现在想知道是否存在一个最小的交换次数来完成奖牌的整理工作。

为了便于表示,定义 Au 表示金奖, Ag 表示银奖, Cu 表示铜奖。

输入描述

单组输入,输入共 1 行

一行非空字符串 s ,表示奖牌的顺序,保证字符串中不含空格且字符串长度不大于210^6*

输出描述

输出一个整数,表示重薪排序,完成整理工作所需的最小交换次数。

样例输入 1

AuCuAg

样例输出 1

1

样例输入 2

AgAuAuAgCuAgAuCuCu

样例输出 2

2

样例解释

对于第 1 组样例 AuCuAg ,只要将第 2 个位置上的奖牌与第 3 个位置上奖牌交换即可满足条件,所以输出最小交换次数为 1 。

对于第 2 组样例 AgAuAuAgCuAgAuCuCu ,先将第 5 个奖牌与第 7 个位置上的奖牌交换,再将第 5 个与第 1 个交换即可满足条件,所以输出最小交换次数 2。

解题思路:

我们将字符串转换成123的数字,按照从小到大进行一次排序,跟原来的顺序对比,建立一个有权图,,由 u 指向 v 的边权为 w 边表示有 w 个 u 放在 v 位置。
交换位置只有两种合法的交换,一种是用一次操作对两个交换,另一种是用两次操作对三个顺次交换位置。显然最优解是能互换的先互换,剩下的一定是成一个环,直接环上权乘2累计进答案即可

代码:

#include<bits/stdc++.h>
using namespace std;
string s;
const int N=1e6+5;
int len,n;
int a[N],b[N];
int p[5][5];
int ans,tmp;
int x,y,z;
int main() {
	cin >> s;
	len = s.length();
	n = len/2;
	for(int i=0; i<len; i+=2) {
		if(s.substr(i,2) == "Au") {
			a[i/2] = 1;
		} else if(s.substr(i,2) == "Ag"){
			a[i/2] = 2;
		} else if(s.substr(i,2) == "Cu"){
			a[i/2] = 3;
		}
		b[i/2] = a[i/2];
	}
	sort(b,b+n);
	for(int i=0; i<n; i++) {
		for(int x=1; x<=3; x++) {
			for(int y=1; y<=3; y++) {
				if(b[i] == x && a[i] == y) {
					p[x][y]++;
				}
			}
		}
	}
	tmp = min(p[1][2],p[2][1]);
	p[1][2]-=tmp;p[2][1]-=tmp;
	ans += tmp;
	
	tmp = min(p[1][3],p[3][1]);
	p[1][3]-=tmp;p[3][1]-=tmp;
	ans += tmp;
	
	tmp = min(p[2][3],p[3][2]);
	p[2][3]-=tmp;p[3][2]-=tmp;
	ans += tmp;
	
	tmp = max(p[1][2],p[2][1]);
	ans += tmp*2;
	printf("%d",ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shirandexiaowo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值