Kuro K u r o 、 Shiro S h i r o 和 Katie K a t i e 三人都有一个长度相同的字符串,每个字符串都只包含小写字母和大写字母,三个人都有 n n 次对自己的字符串进行操作的机会,每次操作可以选择一个字符并将这个字符修改成另一个字符。一个字符串的价值定义为这个字符串中所有子串出现的最大次数,他们三人经过 轮操作后,在采取最优策略下,谁的字符串价值将会最大。
第一行为一个整数 n (0≤n≤109) n ( 0 ≤ n ≤ 10 9 ) ,接下去三行为三个字符串,分别为 Kuro,Shiro K u r o , S h i r o 和 Katie K a t i e 的初始字符串,字符串的长度不超过 105 10 5 ,字符串只包含小写字母和大写字母。
输出三人都采取最优策略下,字符串价值最大的人,如果存在两个或两个以上最大价值,输出 Draw D r a w 。
输入 |
---|
3Kuroo Shiro Katie |
输出 |
Kuro |
提示 |
3
3
轮之后, 可以将自己的字符串修改为 ooooo ,价值为
5
5
,而另外两个人最多只能得到价值为 的字符串。 |
输入 |
---|
7treasurehunt threefriends hiCodeforces |
输出 |
Shiro |
输入 |
---|
1abcabc cbabac ababca |
输出 |
Katie |
输入 |
---|
15foPaErcvJ mZaxowpbt mkuOlaHRE |
输出 |
Draw |
提示 |
每个人都可以将自己的字符串修改成 9 9 个相同的字符,因此三人平局。 |
如果某个长度大于 的子串是字符串中出现次数最多的子串,那么这个子串中的字符一定也是出现最多的子串,因此只要处理所有字符即可,对于每个人都计算出可能的最大价值再进行比较就能知道赢家。如果某个字符串的字符完全相等且 n n 等于 ,那么这个符串的价值只能等于 |s|−1 | s | − 1 ,如果 Max+n≤|s| M a x + n ≤ | s | (其中 Max M a x 为字符出现的最大次数),那么最大价值就是 Max+n M a x + n ,否则字符串的价值就可以达到 |s| | s | 。
过题代码
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <climits> #include <cstring> #include <string> #include <vector> #include <list> #include <queue> #include <stack> #include <map> #include <set> #include <functional> #include <algorithm> using namespace std; #define LL long long const int maxn = 100000 + 100; int n; char str[3][maxn]; int score[3]; map<char, int> mp[3]; int len[3]; map<int, int> mpp; map<int, int>::iterator it; int getscore(int Index, char ch) { int tmp = n - (len[Index] - mp[Index][ch]); if(tmp >= 0) { if(mp[Index][ch] == len[Index] && tmp == 1) { return len[Index] - 1; } return len[Index]; } return n + mp[Index][ch]; } int main() { #ifdef LOCAL freopen("test.txt", "r", stdin); // freopen("10.out", "w", stdout); #endif // LOCAL while(scanf("%d", &n) != EOF) { mpp.clear(); memset(score, 0, sizeof(score)); for(int i = 0; i < 3; ++i) { mp[i].clear(); scanf("%s", str[i]); len[i] = strlen(str[i]); for(int j = 0; str[i][j]; ++j) { ++mp[i][str[i][j]]; } } for(char ch = 'a'; ch <= 'z'; ++ch) { for(int i = 0; i < 3; ++i) { score[i] = max(score[i], getscore(i, ch)); } } for(char ch = 'A'; ch <= 'Z'; ++ch) { for(int i = 0; i < 3; ++i) { score[i] = max(score[i], getscore(i, ch)); } } int Max = 0; for(int i = 0; i < 3; ++i) { Max = max(Max, score[i]); ++mpp[score[i]]; } int cnt = 0; int ans = 0; for(int i = 0; i < 3; ++i) { if(score[i] == Max) { ++cnt; ans = i; } } if(cnt >= 2) { printf("Draw\n"); } else { switch(ans) { case 0: printf("Kuro\n"); break; case 1: printf("Shiro\n"); break; case 2: printf("Katie\n"); break; } } } return 0; }