标题:交换次数 IT产业人才需求节节攀升。业内巨头百度、阿里巴巴、腾讯(简称BAT)在某海滩进行招聘活动。 招聘部门一字排开。因为是自由抢占席位,三大公司的席位随机交错在一块儿,形如: ABABTATT,这使得应聘者十分别扭。 因而,管理部门要求招聘方进行必要的交换位置,使得每一个集团的席位都挨在一块儿。即最后形如: BBAAATTT 这样的形状,固然,也多是: AAABBTTT 等。 如今,假设每次只能交换2个席位,而且知道如今的席位分布, 你的任务是计算:要使每一个集团的招聘席位都挨在一块儿须要至少进行多少次交换动做。 输入是一行n个字符(只含有字母B、A或T),表示如今的席位分布。 输出是一个整数,表示至少交换次数。 好比,输入: TABTABBTTTT 程序应该输出: 3 再好比,输入: TTAAABB 程序应该输出: 0 咱们约定,输入字符串的长度n 不大于10万 资源约定: 峰值内存消耗(含虚拟机) < 256M CPU消耗 < 1000ms
首页经过题目能够知道,排序的方式有六种,分别是:ios
上面其实就是 ABT 的六种组合。咱们要作的就是将输入的字符串,根据上面的每一种组合,每个字符交换到正确的位置上。例如输入TABTAB
,排序方式为ABT
,就须要将两个AA
交换到第 0 位和第 1 位,将两个BB
交换到第 2 位和第 3 位,最后两个TT
就是必定会在倒数第二位和第一位。由此可的,咱们只须要根据每一种组合,知道ABT
的前后排序顺序,依次交换直到符合条件,六组里最少交换次数的就是最后的答案。spa
使用对拍程序生成 10 万的数据,可以在本机 1 秒内执行。
#include <iostream> #include <algorithm> #include <cstdio> #include <cmath> #include <vector> #include <map> #include <fstream> using namespace std; string s; map<char, int> M; // ABT 出现的组合状况 char per[6][3] = { {'A', 'B', 'T'}, {'A', 'T', 'B'}, {'B', 'A', 'T'}, {'B', 'T', 'A'}, {'T', 'A', 'B'}, {'T', 'B', 'A'}, }; int minimumSwapCount (char com[]) { map<char, int> m1, m2, m3; char c1 = com[0], c2 = com[1], c3 = com[2]; int l = 0; int r = M[c1]; int res = 0; for (int i = l; i < r; i++) m1[s[i]]++; l = r; r = l + M[c2]; for (int i = l; i < r; i++) m2[s[i]]++; l = r; r = s.length(); for (int i = l; i < r; i++) m3[s[i]]++; // printf("A = %d, B = %d, T = %d\n", m1['A'], m1['B'], m1['T']); // printf("A = %d, B = %d, T = %d\n", m2['A'], m2['B'], m2['T']); // printf("A = %d, B = %d, T = %d\n", m3['A'], m3['B'], m3['T']); // cout << endl; // m1 只能有 c1 存在,c2 和 c3 都须要与 m2, m3 交换 while (m1[c2]) { if (m2[c1]) { m1[c1]++; m2[c1]--; m1[c2]--; m2[c2]++; res++; } else if (m3[c1]) { m1[c1]++; m3[c1]--; m1[c2]--; m3[c2]++; res++; } } while (m1[c3]) { if (m2[c1]) { m1[c1]++; m2[c1]--; m1[c3]--; m2[c3]++; res++; } else if (m3[c1]) { m1[c1]++; m3[c1]--; m1[c3]--; m3[c3]++; res++; } } // m1 通过与 m2 和 m3 的交换后,m1 里只会保留 c1 // m2 里可能还有 c2 和 c3 的值,与 m3 交换 while (m2[c3]) { if (m3[c2]) { m2[c2]++; m3[c2]--; m2[c3]--; m3[c3]++; res++; } } // 通过上面的循环,m1 内只有 c1,m2 内只有 c2,由此 m3 内只会有 c3 // 返回本次组合的交换次数 return res; } int main () { cin >> s; // ifstream infile; // infile.open("in.txt"); // infile >> s; int n = s.length(), ans = 1 << 21; // 求出输入字符串中,A、B 和 T 的出现次数 for (int i = 0; i < n; i++) M[s[i]]++; // 求每种组合最小的交换次数 for (int i = 0; i < 6; i++) ans = min(ans, minimumSwapCount(per[i])); cout << ans << endl; return 0; }