【LOJ】#2511. 「BJOI2018」双人猜数游戏
题解
设\(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」双人猜数游戏的更多相关文章
- LOJ #2135. 「ZJOI2015」幻想乡战略游戏
#2135. 「ZJOI2015」幻想乡战略游戏 链接 分析: 动态点分治,求加权重心,带修改. 考虑如果知道了一个点s,如何求答案,那么首先可以点分治的思想,求每个联通块内所有点到分治中心距离和,然 ...
- [BJOI2018]双人猜数游戏
题解: 彻彻底底的思维题???还是挺难的.. 首先连样例解释都没给..没看题解搞了很久 大概就是 一个人要根据另一个人的决策来猜数 可以去看洛谷那篇题解的解释 然后我们用$f[A/B][i][j][k ...
- LOJ #2135. 「ZJOI2015」幻想乡战略游戏(点分树)
题意 给你一颗 \(n\) 个点的树,每个点的度数不超过 \(20\) ,有 \(q\) 次修改点权的操作. 需要动态维护带权重心,也就是找到一个点 \(v\) 使得 \(\displaystyle ...
- 洛谷P4459/loj#2511 [BJOI2018]双人猜数游戏(博弈论)
题面 传送门(loj) 传送门(洛谷) 题解 所以博弈论的本质就是爆搜么-- 题解 //minamoto #include<bits/stdc++.h> #define R registe ...
- [luogu4459][BJOI2018]双人猜数游戏(DP)
https://zhaotiensn.blog.luogu.org/solution-p4459 从上面的题解中可以找到样例解释,并了解两个人的思维方式. A和B能从“不知道”到“知道”的唯一情况,就 ...
- 【洛谷4459】[BJOI2018] 双人猜数游戏(动态规划)
点此看题面 大致题意: 一直有两个数\(m,n\),已知\(s\le m\le n\),且\(Alice\)和\(Bob\)二个"最强大佬"各知道\(mn\)和\(m+n\).每轮 ...
- loj 2135 「ZJOI2015」幻想乡战略游戏 - 动态点分治
题目传送门 传送门 题目大意 给定一棵树,初始点权都为0,要求支持: 修改点权 询问带权重心 询问带权重心就在点分树上跑一下就行了.(枚举跳哪个子树更优) 剩下都是基础点分治. 学了一下11-dime ...
- Loj #3089. 「BJOI2019」奥术神杖
Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...
- Loj #2542. 「PKUWC2018」随机游走
Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...
随机推荐
- Could not load file or assembly 'Microsoft.ReportViewer.WebForms, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91' or one of its dependencies
my shurufa huai diao le 1\ first you need install " SQLSysClrTypes_x86.msi " 2\ ...
- 【NOIP 2018】保卫王国(动态dp / 倍增)
题目链接 这个$dark$题,嗯,不想说了. 法一:动态$dp$ 虽然早有听闻动态$dp$,但到最近才学,如果你了解动态$dp$,那就能很轻松做出这道题了.故利用这题在这里科普一下动态$dp$的具体内 ...
- java同步代码(synchronized)中使用BlockingQueue
说起BlockingQueue,大家最熟悉的就是生产者-消费者模式下的应用.但是如果在调用queue的上层代码加了同步块就会导致线程死锁. 例如: static BlockingQueue<St ...
- First non-repeating character in a stream
First non-repeating character in a stream Given an input stream of n characters consisting only of s ...
- java基础基础总结----- System
常用的方法: 细节分析:
- win32 ini
原文:https://www.cnblogs.com/qq78292959/archive/2012/06/10/2544389.html Windows操作系统专门为此提供了6个API函数来对配置设 ...
- Java基础-SSM之Spring的AOP编程
Java基础-SSM之Spring的AOP编程 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Spring的本质说白了就是动态代理,接下来我们会体验AOP的用法.它是对OOP的 ...
- DataGridView更新数据到数据库
WinFrom程序绑定了一个DataGridView控件,我需要添加一个button按钮来更改状态,还需要把更新之后的状态更新到数据库,如下图所示的这样: 首先先来拖控件,把界面做出来,自己拖一个Da ...
- Linux(Debian)软件安装
# 配置/etc/apt/sources.list 通过root权限修改/etc/apt/sources.list $ su #输入密码进入root权限 $ chmod 0666 /etc/apt/s ...
- JMS学习(五)--ActiveMQ中的消息的持久化和非持久化 以及 持久订阅者 和 非持久订阅者之间的区别与联系
一,消息的持久化和非持久化 ①DeliveryMode 这是传输模式.ActiveMQ支持两种传输模式:持久传输和非持久传输(persistent and non-persistent deliver ...