题解

设\(f[p][a][b]\)表示询问了\(p\)次,答案是\(a,b\)是否会被猜出来

然后判断如果\(p = 1\)

第一个问的\(Alice\),那么\([s,\sqrt{nm}]\)约数只有一个,\(f[p][a][b] = 1\)否则为\(0\)

如果第一个问的\(Bob\),那么\(a + b - 2 * S <= 1\)那么\(f[p][a][b] = 1\)否则为\(0\)

剩下的按照\(p\)这次操作询问谁,且然后从可能的数对里找\(f[p - 1][i][j]\)为\(0\)的有几个,如果只有1个就猜出来了

同时还要保证,在某个人猜出来之后,另一个猜出来的人询问第\(T + 1\)回合刚好能被猜出来的数对中,也只会问出一个,那么答案就是\(a,b\)了

用记搜,跑得还是挺快的

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
#define MAXN 20005
#define eps 1e-8
#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
int f[25][505][505],cnt[505 * 505],g[505][505];
vector<int> v[505 * 505];
int S,T,k;
char c[25];
bool dp(int p,int a,int b) {
if(p == 0) return 0;
if(f[p][a][b] != -1) return f[p][a][b];
if(p == 1) {
if(k == 1) { if(cnt[a * b] > 1) f[p][a][b] = 0;
else f[p][a][b] = 1;
}
else {
if(a + b - 2 * S <= 1) f[p][a][b] = 1;
else f[p][a][b] = 0;
}
return f[p][a][b];
}
if(dp(p - 1,a,b)) return f[p][a][b] = 1;
if(p % 2 == k) {
int c = 0;
for(auto h : v[a * b]) {
if(!dp(p - 1,h,a * b / h)) ++c;
}
if(c == 1) f[p][a][b] = 1;
else f[p][a][b] = 0;
}
else {
int c = 0;
for(int i = S ; i <= (a + b) / 2 ; ++i) {
if(!dp(p - 1,i,a + b - i)) ++c;
}
if(c == 1) f[p][a][b] = 1;
else f[p][a][b] = 0;
}
return f[p][a][b];
}
bool check(int a,int b) {
if(g[a][b] != -1) return g[a][b];
int c = 0;
if((T + 2) % 2 == k) {
for(auto h : v[a * b]) {
if(dp(T + 1,h,a * b / h) && !dp(T,h,a * b / h)) ++c;
}
}
else {
for(int i = S ; i <= (a + b) / 2 ; ++i) {
if(dp(T + 1,i,a + b - i) && !dp(T,i,a + b - i)) ++c;
}
}
if(c == 1) g[a][b] = 1;
else g[a][b] = 0;
return g[a][b];
}
pii Solve() {
memset(f,-1,sizeof(f));
memset(cnt,0,sizeof(cnt));
memset(g,-1,sizeof(g));
for(int i = S * S ; i <= 500 * 500 ; ++i) {
int t = sqrt(i);
v[i].clear();
for(int j = S ; j <= t ; ++j) {
if(i % j == 0) {
cnt[i]++;
v[i].pb(j);
}
}
}
for(int s = S + S ; s <= 1000 ; ++s) {
for(int i = S ; i <= 500 ; ++i) {
if(i > s) break;
for(int j = i ; j <= s - i ; ++j) {
if(i + j > s) break;
if(dp(T + 1,i,j) && !dp(T,i,j) && check(i,j)) {return mp(i,j);}
}
}
}
}
int main() {
for(int i = 1 ; i <= 25 ; ++i) {
stringstream ss;
string num;
ss << i;
ss >> num;
string str1 = "guess/guess" + num + ".in";
FILE *fin = fopen(str1.c_str(),"r");
fscanf(fin,"%d%s%d",&S,c + 1,&T); string str2 = "answer/guess" + num + ".out";
FILE *fout = fopen(str2.c_str(),"w");
if(c[1] == 'A') k = 1;
else k = 0;
pii ans = Solve();
fprintf(fout,"%d %d\n",ans.fi,ans.se);
printf("OK with %d task\n",i);
}
return 0;
}

【LOJ】#2511. 「BJOI2018」双人猜数游戏的更多相关文章

  1. LOJ #2135. 「ZJOI2015」幻想乡战略游戏

    #2135. 「ZJOI2015」幻想乡战略游戏 链接 分析: 动态点分治,求加权重心,带修改. 考虑如果知道了一个点s,如何求答案,那么首先可以点分治的思想,求每个联通块内所有点到分治中心距离和,然 ...

  2. [BJOI2018]双人猜数游戏

    题解: 彻彻底底的思维题???还是挺难的.. 首先连样例解释都没给..没看题解搞了很久 大概就是 一个人要根据另一个人的决策来猜数 可以去看洛谷那篇题解的解释 然后我们用$f[A/B][i][j][k ...

  3. LOJ #2135. 「ZJOI2015」幻想乡战略游戏(点分树)

    题意 给你一颗 \(n\) 个点的树,每个点的度数不超过 \(20\) ,有 \(q\) 次修改点权的操作. 需要动态维护带权重心,也就是找到一个点 \(v\) 使得 \(\displaystyle ...

  4. 洛谷P4459/loj#2511 [BJOI2018]双人猜数游戏(博弈论)

    题面 传送门(loj) 传送门(洛谷) 题解 所以博弈论的本质就是爆搜么-- 题解 //minamoto #include<bits/stdc++.h> #define R registe ...

  5. [luogu4459][BJOI2018]双人猜数游戏(DP)

    https://zhaotiensn.blog.luogu.org/solution-p4459 从上面的题解中可以找到样例解释,并了解两个人的思维方式. A和B能从“不知道”到“知道”的唯一情况,就 ...

  6. 【洛谷4459】[BJOI2018] 双人猜数游戏(动态规划)

    点此看题面 大致题意: 一直有两个数\(m,n\),已知\(s\le m\le n\),且\(Alice\)和\(Bob\)二个"最强大佬"各知道\(mn\)和\(m+n\).每轮 ...

  7. loj 2135 「ZJOI2015」幻想乡战略游戏 - 动态点分治

    题目传送门 传送门 题目大意 给定一棵树,初始点权都为0,要求支持: 修改点权 询问带权重心 询问带权重心就在点分树上跑一下就行了.(枚举跳哪个子树更优) 剩下都是基础点分治. 学了一下11-dime ...

  8. Loj #3089. 「BJOI2019」奥术神杖

    Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...

  9. Loj #2542. 「PKUWC2018」随机游走

    Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...

随机推荐

  1. IDEA中新建Module时Module name、Content root、Module file location的含义

    如下图测试: 最开始默认情况下,Content root.Module file location两行,最末尾的数据跟Module name是相同的. 现在对三行数据,强制进行不同的命名,Finish ...

  2. caffe多任务、多标签

    解决的目标问题:多分类问题,比如车辆的外形和颜色,苹果的大小和颜色:多任务:车牌角点的定位和车牌的颜色.定位在技术上属于回归,车牌颜色判断则属于分类. 技术点 caffe默认是单输入任务单标签的,也就 ...

  3. 【BZOJ1024】[SCOI2009]生日快乐(搜索)

    [BZOJ1024][SCOI2009]生日快乐(搜索) 题面 BZOJ 洛谷 题解 看到这个数据范围就感觉是爆搜.我们爆搜左右分成多少块,这样子左右的面积已知,再枚举一下横着切还是竖着切,这样子就可 ...

  4. 【hdu1542】线段树求矩形面积并

    分割线内容转载自http://hzwer.com/879.html ------------------------------------------------------------------ ...

  5. Java基础-JVM调优策略简介

    Java基础-JVM调优策略简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.JVM结构分析 1>.JVM结构图 2>.JVM运行时数据区功能说明 JVM管理的内 ...

  6. .net MVC框架里怎么写控件

    .net的MVC框架如果选择了Razor引擎就需要自己来写控件了,这里列出了一些简单的控件的书写方法 @*这是TextBox控件的写法*@ @Html.TextBox("textbox1&q ...

  7. 【DS】排序算法之选择排序(Selection Sort)

    一.算法思想 选择排序是一种简单直观的排序算法.它的工作原理如下: 1)将序列分成两部分,前半部分是已经排序的序列,后半部分是未排序的序列: 2)在未排序序列中找到最小(大)元素,放到已排序序列的末尾 ...

  8. POJ - 3026 Borg Maze(最小生成树)

    https://vjudge.net/problem/POJ-3026 题意 在一个y行 x列的迷宫中,有可行走的通路空格’ ‘,不可行走的墙’#’,还有两种英文字母A和S,现在从S出发,要求用最短的 ...

  9. 那些年的 网络通信之 UDP 数据报包传输---

    下面是 一个多线程,基于 UDP 用户数据报包 协议 的 控制台聊天小程序 import java.io.*; import java.net.*; class Send implements Run ...

  10. A Brief Overview of Deep Learning

    A Brief Overview of Deep Learning (This is a guest post by Ilya Sutskever on the intuition behind de ...