6. 花魁之争
解题思路:
根据题意,对于每一次操作,每个仙女来说都取最优解,那第一次每个仙女都操作一次,这时候胜出的仙女,是一定赢的。所以,只要计算n个字符串操作一次的最优字符串,然后,选出最小字符串有几个就是答案。
如何操作一次,支付串字典序最小?
- 存在这样的i和j,直接交换
i < j && s[ i ] > s[ j ]
s[j]尽量小的情况下j尽量大 - 存在两个相同的字符(容易漏掉)
- 交换最后两个字符(容易漏掉)
#include <iostream>
#include<vector>
using namespace std;
const int N = 1e5 + 10;
vector<string> vs;
int n;
string cal(string &s) {
vector<int> ps[26];
int len = s.size();
for (int i = 0; i < len; i++) {
ps[s[i] - 'a'].push_back(i);
}
for (int i = 0; i < len; i++) {
for (int j = 0; j < s[i] - 'a'; j++) {
int tl = ps[j].size();
if (tl && ps[j][tl - 1] > i) {
swap(s[i], s[ps[j][tl - 1]]);
return s;
}
}
}
for (int i = 0; i < 26; i++) {
if (ps[i].size() > 1) return s;
}
swap(s[len - 1], s[len - 2]);
return s;
}
int main()
{
string s, mi = "";
cin >> n;
int ans = 0;
for (int i = 0; i < n; i++) {
cin >> s;
s = cal(s);
// cout << s <<endl;
if (mi == "" || mi > s) {
mi = s;
ans = 1;
}else if (mi == s) ans++;
}
cout << ans;
return 0;
}