第九届 蓝桥杯 决赛 交换次数

问题描述


IT产业人才需求节节攀升。业内巨头百度、阿里巴巴、腾讯(简称BAT)在某海滩进行招聘活动。
招聘部门一字排开。由于是自由抢占席位,三大公司的席位随机交错在一起,形如:
ABABTATT,这使得应聘者十分别扭。
于是,管理部门要求招聘方进行必要的交换位置,使得每个集团的席位都挨在一起。即最后形如:
BBAAATTT 这样的形状,当然,也可能是:
AAABBTTT 等。

现在,假设每次只能交换2个席位,并且知道现在的席位分布,
你的任务是计算:要使每个集团的招聘席位都挨在一起需要至少进行多少次交换动作。

输入是一行n个字符(只含有字母B、A或T),表示现在的席位分布。
输出是一个整数,表示至少交换次数。

比如,输入:
TABTABBTTTT

程序应该输出:
3

再比如,输入:
TTAAABB

程序应该输出:
0

我们约定,输入字符串的长度n 不大于10万

资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗  < 1000ms


请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。
 

Java

import java.util.Scanner;

public class 交换次数 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		char[] ss = scanner.next().toCharArray();
		//六种排列组合的方案
		char[][] c = {
				{'B','A','T'},
				{'B','T','A'},
				{'A','B','T'},
				{'A','T','B'},
				{'T','A','B'},
				{'T','B','A'}
		};
		
		int ans = Integer.MAX_VALUE;
		for(int i = 0;i < 6;i++) {
			ans = Math.min(ans,fun(ss,c[i][0],c[i][2],c[i][2]));
		}
		System.out.println(ans);
	}
	//将整个字符串分为三个区域
	public static int fun(char[] ss,char A,char B,char C) {
		//A区域中a的个数
		int a = 0;
		//B区域中b的个数
		int b = 0;
		//A区域中非a的个数
		int Abc = 0;
		//A区域中b的个数
		int Ab = 0;
		//B区域中a的个数
		int Ba = 0;
		//B区域中c的个数
		int Bc = 0;
		int len = ss.length;
		//求出A和B两个区域占的大小
		for(int i = 0;i < len;i++) {
			if(ss[i] == A) a++;
			if(ss[i] == B) b++;
		}
		for(int i = 0;i < a;i++) {
			if(ss[i] != A) Abc++;
			if(ss[i] == B) Ab++;
		}
		for(int i = a;i < a + b;i++) {
			if(ss[i] == A) Ba++;
			if(ss[i] == C) Bc++;
		}
		//最小交换次数是:将A区域非a的交换出去,B区域非b的交换出去
		//因为A区域中有b,B区域中有a,他们直接交换就行,再减去重复的交换次数
		return Abc + Bc + Ba - Math.min(Ba, Ab);
	}

}

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

@小红花

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

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

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

打赏作者

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

抵扣说明:

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

余额充值