[蓝桥杯 2018 国 C] 交换次数
题目描述
IT 产业人才需求节节攀升。业内巨头百度、阿里巴巴、腾讯(简称 BAT)在某海滩进行招聘活动。
招聘部门一字排开。由于是自由抢占席位,三大公司的席位随机交错在一起,形如:
ABABTATT
,这使得应聘者十分别扭。
于是,管理部门要求招聘方进行必要的交换位置,使得每个集团的席位都挨在一起。即最后形如:
BBAAATTT
这样的形状,当然,也可能是:
AAABBTTT
等。
现在,假设每次只能交换 2 2 2 个席位,并且知道现在的席位分布,
你的任务是计算:要使每个集团的招聘席位都挨在一起需要至少进行多少次交换动作。
输入格式
输入是一行 n n n 个字符(只含有字母 B
、A
或 T
),表示现在的席位分布。
输出格式
输出是一个整数,表示至少交换次数。
样例 #1
样例输入 #1
TABTABBTTTT
样例输出 #1
3
样例 #2
样例输入 #2
TTAAABB
样例输出 #2
0
提示
输入字符串的长度 n n n 不大于 1 0 5 10^5 105。
时限 1 秒, 256M。蓝桥杯 2018 年第九届国赛
题目思路
根据题目描述,我们需要将输入的字符串中的字符重新排列,使得每个集团的席位都挨在一起。每次只能交换两个相邻的席位,我们需要计算至少进行多少次交换才能满足条件。
一种解决方法是使用贪心算法。我们可以从左到右遍历字符串,统计每个集团的席位数量,然后根据数量的大小进行交换。具体步骤如下:
1.初始化交换次数为0。
2.统计每个集团的席位数量。
3.如果集团的席位数量不满足挨在一起的条件,即存在相邻集团的席位数量之差大于1,找到数量最多的两个相邻集团。
4.将这两个相邻集团的席位进行交换,并将交换次数加1。
5.重复步骤3和步骤4,直到所有集团的席位都挨在一起。
6.输出交换次数。
下面是用C++实现的代码示例:
cpp
#include<bits/stdc++.h>
using namespace std;
string a;
int A[10005],B[10005],T[10005];
string m[7] = {"0","ABT","ATB","BTA","BAT","TAB","TBA"};
int dfs(string x)
{
int a_ = 0,b_ = 0,t_ = 0;
for(int i = 0;i < a.size();i++)
{
if(a[i] == x[0])
a_++;
if(a[i] == x[1])
b_++;
if(a[i] == x[2])
t_++;
}
int abt = 0,ab = 0;
for(int i = 0;i < a_;i++)
{
if(a[i] != x[0])
abt++;
if(a[i] == x[1])
ab++;
}
int bt = 0,ba = 0;
for(int i = a_;i < a_ + b_;i++)
{
if(a[i] == x[2])
bt++;
if(a[i] == x[0])
ba++;
}
int ans = abt + bt;
if(ba > ab)
ans += ba - ab;
return ans;
}
int main()
{
cin >> a;
//B = 66,A = 65,T = 84
//abt atb bta bat tab tba
int minn = 1e7;
for(int i = 1;i <= 6;i++)
{
minn = min(minn,dfs(m[i]));
}
cout << minn <<endl;
return 0;
}
这样,我们就可以计算出至少交换的次数来满足条件。