再乱交估计就要封号了hhh
#include<bits/stdc++.h>
//#include"word.h"
using namespace std;
mt19937 rd(time(0));
const int N = 8879;
int n, test, ans, f[N][N];
char c[N][6], feedback[N][N][6];
int firstguess[30] = {7008,4223,4223,7897,7614,382,4223,4223,7077,5406,6131,5085,7612,147,7973,4223,6104,147,5747,5085,7077,6346,5085,1560,3971,98};
void init(int num_scramble, const char *scramble)
{
n = num_scramble;
for(int i = 0; i < n; i++)
for(int j = 0; j < 5; j++)
c[i][j] = scramble[i * 5 + j];
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
{
static bool flag[30];
for(int k = 0; k < 5; k++)
if(c[i][k] == c[j][k]) feedback[i][j][k] = 'g';
else feedback[i][j][k] = '-', flag[c[j][k] - 'a'] = 1;
for(int k = 0; k < 5; k++)
if(feedback[i][j][k] == '-' && flag[c[i][k] - 'a'])
feedback[i][j][k] = 's';
for(int k = 0; k < 5; k++) flag[c[j][k] - 'a'] = 0;
// static int flag[30];
// for(int k = 0; k < 5; k++)
// if(c[i][k] == c[j][k]) feedback[i][j][k] = 'g';
// else feedback[i][j][k] = '-', flag[c[j][k] - 'a']++;
// for(int k = 0; k < 5; k++)
// if(feedback[i][j][k] == '-' && flag[c[i][k] - 'a'])
// feedback[i][j][k] = 's', flag[c[i][k] - 'a']--;
// for(int k = 0; k < 5; k++) flag[c[j][k] - 'a'] = 0;
for(int k = 0; k < 5; k++)
{
f[i][j] *= 3;
if(feedback[i][j][k] == 'g') f[i][j]++;
else if(feedback[i][j][k] == 's') f[i][j] += 2;
}
}
}
vector<int> res;
const char *guess(int num_testcase, int remaining_guesses, char initial_letter, bool *gold, bool *silver)
{
if(test != num_testcase)
{
test = num_testcase;
res.clear();
for(int i = 0; i < n; i++)
if(c[i][0] == initial_letter)
res.push_back(i);
ans = firstguess[initial_letter - 'a'];
}
else
{
int s = 0;
for(int i = 0; i < 5; i++)
{
s *= 3;
if(gold[i]) s++;
else if(silver[i]) s += 2;
}
vector<int> res1;
for(int i : res)
if(f[ans][i] == s)
res1.push_back(i);
res = res1;
shuffle(res.begin(), res.end(), rd);
ans = 0;
double maxn = 0;
for(int i = 0; i < n; i++)
{
static int cnt[243];
double sum = 0;
for(int j : res)
{
if(i == j) sum = 1.35 / res.size() + 0.10618;
cnt[f[j][i]]++;
}
for(int j = 0; j < 243; j++)
if(cnt[j]) sum -= 1.0 * cnt[j] / res.size() * log2(1.0 * cnt[j] / res.size()), cnt[j] = 0;
if(sum > maxn) ans = i, maxn = sum;
}
}
return c[ans];
}
//const char *guess1(int num_testcase, int remaining_guesses, char initial_letter, bool *gold, bool *silver)
//{
// if(test != num_testcase)
// {
// test = num_testcase;
// res.clear();
// for(int i = 0; i < n; i++)
// if(initial_letter == '?' || c[i][0] == initial_letter)
// res.push_back(i);
// shuffle(res.begin(), res.end(), rd);
// ans = firstguess[initial_letter - 'a'];
// }
// else
// {
// int s = 0;
// for(int i = 0; i < 5; i++)
// {
// s *= 3;
// if(gold[i]) s++;
// else if(silver[i]) s += 2;
// }
//
// vector<int> res1;
// for(int i : res)
// if(f[ans][i] == s)
// res1.push_back(i);
// res = res1;
//
// ans = 0;
// double maxn = 0;
// for(int i = 0; i < n; i++)
// {
// static int cnt[243];
// double sum = 0;
// for(int j : res)
// {
// if(i == j) sum = 3.92 / res.size();
// cnt[f[j][i]]++;
// }
// for(int j = 0; j < 243; j++)
// if(cnt[j]) sum -= 1.0 * cnt[j] / res.size() * log2(1.0 * cnt[j] / res.size()), cnt[j] = 0;
// if(sum > maxn) ans = i, maxn = sum;
// }
// }
//
// printf("%s %d\n", c[ans], res.size());
// if(res.size() <= 20)
// {
// printf("all words: ");
// for(int i : res) printf("%s ", c[i]);
// puts("");
// }
// printf("your word: ");
// scanf("%s", c[n]);
// for(int i = 0; i < n; i++)
// if(c[i][0] == c[n][0] && c[i][1] == c[n][1] && c[i][2] == c[n][2] && c[i][3] == c[n][3] && c[i][4] == c[n][4])
// {
// ans = i;
// break;
// }
// return c[ans];
//}