不知道很多轮后就知道了是因为可能的数对在不断减少。
考虑设(f[z][x][y])表示(z)轮后,两个数分别为(x,y)是否能猜出来。
当(z=1)时,(f=可能的数对(u,v)只有一个)。
当(z>1)时
转移1:(f[z][x][y]=f[z-2][x][y])
转移2:枚举所有可能的数对((u,v)),若((u,v)(除(x,y)))在(z-1)轮都被猜出来,则(f[z][x][y]=1)
最后,答案要的是两个人都知道的时间是(t+1)和(t+2)
((x,y))合法的条件:
((x,y))最早知道时间是(t+1),且对于所有可能的数对((u,v)),只有((x,y))在(t+1)知道,那么(t+2)时另一人就可以知道。
利用记忆话搜索+map可以(1s)内出所有解,
Code
#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
#define ff(i, x, y) for(int i = x, _b = y; i < _b; i ++)
#define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
#define ll long long
#define pp printf
#define hh pp("
")
using namespace std;
string in, out, num;
void init(int t) {
num = "";
for(; t; t /= 10) num = ((char) (t % 10 + '0')) + num;
in = "guess" + num + ".in";
out = "guess" + num + ".out";
}
int s, t; char str[105];
const int N = 100005;
map<int, int> bz[18][N], f[18][N];
int dg(int z, int x, int y) {
if(bz[z][x][y]) return f[z][x][y];
bz[z][x][y] = 1;
if(z == 1) {
if(str[0] == 'A') {
int cnt = 0;
fo(i, s, x * y) if(x * y % i == 0 && i <= x * y / i)
cnt ++;
f[z][x][y] = cnt == 1;
} else {
int cnt = 0;
fo(i, s, x + y) if(i <= x + y - i)
cnt ++;
f[z][x][y] = cnt == 1;
}
return f[z][x][y];
}
f[z][x][y] = z > 2 ? dg(z - 2, x, y) : 0;
if(!f[z][x][y]) {
if(((str[0] == 'A') + z) % 2 == 0) {
int cnt = 0;
fo(i, s, x * y) if(x * y % i == 0 && i <= x * y / i) {
cnt += !dg(z - 1, i, x * y / i);
}
if(cnt == 1 && !dg(z - 1, x, y))
f[z][x][y] = 1;
} else {
int cnt = 0;
fo(i, s, x + y) if(i <= x + y - i) {
cnt += !dg(z - 1, i, x + y - i);
}
if(cnt == 1 && !dg(z - 1, x, y))
f[z][x][y] = 1;
}
}
return f[z][x][y];
}
int n;
int qry(int x, int y) {
fo(i, 1, t + 1) if(dg(i, x, y))
return i;
return -1;
}
void work() {
fo(i, 1, 17) fo(j, 1, 1e5) bz[i][j].clear();
scanf("%d", &s);
scanf("%s", str);
scanf("%d", &t);
fo(sum, 2 * s, 100000) {
fo(x, s, sum / 2) {
int y = sum - x;
if(qry(x, y) == t + 1) {
int cnt = 0;
if(((str[0] == 'A') + t) % 2 == 0) {
int cnt = 0;
fo(i, s, x * y) if(x * y % i == 0 && i <= x * y / i) {
cnt += (qry(i, x * y / i) == (t + 1));
}
if(cnt == 1) {
pp("%d %d
", x, y);
return;
}
} else {
int cnt = 0;
fo(i, s, x + y) if(i <= x + y - i) {
cnt += (qry(i, x + y - i) == (t + 1));
}
if(cnt == 1) {
pp("%d %d
", x, y);
return;
}
}
}
}
}
}
int main() {
fo(T, 1, 25) {
fprintf(stderr, "%d
", T);
init(T);
freopen(in.c_str(), "r", stdin);
freopen(out.c_str(), "w", stdout);
work();
}
}