NOI2011真题:兔兔与蛋蛋游戏
NOI2011真题:兔兔与蛋蛋游戏
题目描述
这些天,兔兔和蛋蛋喜欢上了一种新的棋类游戏。
这个游戏是在一个 n行 m 列的棋盘上进行的。游戏开始之前,棋盘上有一个格子是空的,其它的格子中都放置了一枚棋子,棋子或者是黑色,或者是白色。
每一局游戏总是兔兔先操作,之后双方轮流操作,具体操作为:
·兔兔每次操作时,选择一枚与空格相邻的白色棋子,将它移进空格。
·蛋蛋每次操作时,选择一枚与空格相邻的黑色棋子,将它移进空格。
第一个不能按照规则操作的人输掉游戏。为了描述方便,下面将操作“将第x行第y列中的棋子移进空格中”记为 M(x,y)M(x,y)。
例如下面是三个游戏的例子。
最近兔兔总是输掉游戏,而且蛋蛋格外嚣张,于是兔兔想请她的好朋友——你——来帮助她。她带来了一局输给蛋蛋的游戏的实录,请你指出这一局游戏中所有她“犯错误”的地方。
注意:
·两个格子相邻当且仅当它们有一条公共边。
·兔兔的操作是“犯错误”的,当且仅当,在这次操作前兔兔有必胜策略,而这次操作后蛋蛋有必胜策略。
输入格式
输入的第一行包含两个正整数 n,m。
接下来 n 行描述初始棋盘。其中第 i 行包含 m个字符,每个字符都是大写英文字母 X、大写英文字母 O 或点号 . 之一,分别表示对应的棋盘格中有黑色棋子、有白色棋子和没有棋子。其中点号 . 恰好出现一次。
接下来一行包含一个整数 k(1≤k≤1000) ,表示兔兔和蛋蛋各进行了 k 次操作。
接下来 2k 行描述一局游戏的过程。其中第 2i – 1 行是兔兔的第 i 次操作(编号为 i 的操作) ,第 2i 行是蛋蛋的第 i 次操作。每个操作使用两个整数 x,y 来描述,表示将第 x 行第 y列中的棋子移进空格中。
输入保证整个棋盘中只有一个格子没有棋子, 游戏过程中兔兔和蛋蛋的每个操作都是合法的,且最后蛋蛋获胜。
输出格式
输出文件的第一行包含一个整数 r,表示兔兔犯错误的总次数。
接下来 r行按递增的顺序给出兔兔“犯错误”的操作编号。其中第 i 行包含一个整数ai表示兔兔第 i 个犯错误的操作是他在游戏中的第 ai次操作。
输入样例:
1 6
XO.OXO
1
1 2
1 1
输出样例:
1
1
说明提示:
解法:
知识:二分图,博弈论,深度优先搜索
先审清楚题意。A 一步走错的判定:A 走这步之前,A先手采用最优策略必胜;A 走这步之后,B先手采用最优策略必胜。
判断的过程:强制当前点不选,如果它的匹配点仍然能找到新的匹配点,说明有一种最大匹配不包含它,自然它就不是 一定 在最大匹配中。
代码:
#include<bits/stdc++.h>
using namespace std;
const int MAXN=41,MAXS=1601,MAXK=1001;
int n,m,dx[]={0,0,1,-1},dy[]={1,-1,0,0};
int tar[MAXS];
bool vis[MAXS],win[MAXK];
bool bel[MAXN][MAXN],col[MAXN][MAXN],del[MAXS];
vector <int> edge[MAXS],src;
inline int id(int x,int y) {
if(x<1||x>n||y<1||y>m||bel[x][y]!=col[x][y]) return -1;
return (x-1)*m+y;
}
inline bool match(int p) {
if(del[p]) return false;
for(int x:edge[p]) {
if(vis[x]||del[x]) continue;
vis[x]=true;
if(tar[x]==-1||match(tar[x])) {
tar[x]=p;
return true;
}
}
return false;
}
inline int MM() {
int ret=0;
memset(tar,-1,sizeof(tar));
for(int x:src) {
memset(vis,false,sizeof(vis));
if(match(x)) ++ret;
}
return ret;
}
signed main() {
int kx,ky;
cin>>n>>m;
for(int i=1;i<=n;++i) {
for(int j=1;j<=m;++j) {
char ch;
cin>>ch;
if(ch=='.') kx=i,ky=j,bel[i][j]=true;
else bel[i][j]=(ch=='X');
}
}
for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) col[i][j]=((i+j)%2==(kx+ky)%2);
for(int i=1;i<=n;++i) {
for(int j=1;j<=m;++j) {
if(bel[i][j]&&col[i][j]) {
src.push_back(id(i,j));
for(int k:{0,1,2,3}) {
int x=i+dx[k],y=j+dy[k];
if(id(x,y)!=-1) {
edge[id(i,j)].push_back(id(x,y));
}
}
}
}
}
int stdv=MM(),k;
del[id(kx,ky)]=true;
int tmpv=MM();
win[1]=tmpv!=stdv;
stdv=tmpv;
scanf("%d",&k);
vector <int> ans;
for(int i=1;i<=k;++i) {
int tx,ty;
scanf("%d%d",&tx,&ty);
del[id(tx,ty)]=true;
tmpv=MM();
win[i*2]=tmpv!=stdv;
stdv=tmpv;
if(win[i*2]&&win[i*2-1]) ans.push_back(i);
scanf("%d%d",&tx,&ty);
del[id(tx,ty)]=true;
tmpv=MM();
win[i*2+1]=tmpv!=stdv;
stdv=tmpv;
}
printf("%d\n",(int)ans.size());
for(int p:ans) printf("%d\n",p);
return 0;
}
NOI2011真题:兔兔与蛋蛋游戏的更多相关文章
- NOI2011 兔兔与蛋蛋游戏
http://www.lydsy.com/JudgeOnline/problem.php?id=2437 这道题真是极好的. 75分做法: 搜索. 出题人真的挺良心的,前15个数据点的范围都很小,可以 ...
- 【BZOJ 2437】 2437: [Noi2011]兔兔与蛋蛋 (博弈+二分图匹配**)
未经博主同意不得转载 2437: [Noi2011]兔兔与蛋蛋 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 693 Solved: 442 Des ...
- 2437: [Noi2011]兔兔与蛋蛋 - BZOJ
Description Input 输入的第一行包含两个正整数 n.m.接下来 n行描述初始棋盘.其中第i 行包含 m个字符,每个字符都是大写英文字母"X".大写英文字母" ...
- 【BZOJ2437】【NOI2011】兔兔与蛋蛋(博弈论,二分图匹配)
[BZOJ2437][NOI2011]兔兔与蛋蛋(博弈论,二分图匹配) 题面 BZOJ 题解 考虑一下暴力吧. 对于每个状态,无非就是要考虑它是否是必胜状态 这个直接用\(dfs\)爆搜即可. 这样子 ...
- 【bzoj2437】[Noi2011]兔兔与蛋蛋 二分图最大匹配+博弈论
Description Input 输入的第一行包含两个正整数 n.m. 接下来 n行描述初始棋盘.其中第i 行包含 m个字符,每个字符都是大写英文字母"X".大写英文字母&quo ...
- bzoj 2437[Noi2011]兔兔与蛋蛋 黑白染色二分图+博弈+匈牙利新姿势
noi2011 兔兔与蛋蛋 题目大意 直接看原题吧 就是\(n*m\)的格子上有一些白棋和一些黑棋和唯一一个空格 兔兔先手,蛋蛋后手 兔兔要把与空格相邻的其中一个白棋移到空格里 蛋蛋要把与空格相邻的其 ...
- 博弈论(二分图匹配):NOI 2011 兔兔与蛋蛋游戏
Description Input 输入的第一行包含两个正整数 n.m. 接下来 n行描述初始棋盘.其中第i 行包含 m个字符,每个字符都是大写英文字母"X".大写英文字母&quo ...
- 第三届蓝桥杯 c/c++真题
第三届蓝桥杯真题 c/c++ 以下题目我自己也并不是所有的题目都是一次性就能做对或是有结题思路的.有些题目也是经过查证网上相关的资料或是参考了别人的代码和解题思路才做出来的.总的来看,这份题目考了很多 ...
- 蓝桥杯java历年真题及答案整理1~20.md
蓝桥杯java历年真题及答案整理(闭关一个月,呕心沥血整理出来的) 1 算法是这样的,如果给定N个不同字符,将这N个字符全排列,最终的结果将会是N!种.如:给定 A.B.C三个不同的字符,则结果为:A ...
- Noip前的大抱佛脚----Noip真题复习
Noip前的大抱佛脚----Noip真题复习 Tags: Noip前的大抱佛脚 Noip2010 题目不难,但是三个半小时的话要写四道题还是需要码力,不过按照现在的实力应该不出意外可以AK的. 机器翻 ...
随机推荐
- docker-compose总结
docker-compose.yml 样例: 各个标签的含义在注释里 version: '3' # 选择的docker-compose 版本 services: # 要编排的一组服务 fim-mysq ...
- JavaWeb核心篇(2)——Request和Response
JavaWeb核心篇(2)--Request和Response 上篇文章中提及到了Servlet,在Servlet中我们主要继承了HTTPServlet类,在HTTPServlet类中我们会接触到两个 ...
- 基于 Gitea 服务端渲染的 Jupyter Notebooks
本指南将向您展示如何通过配置外部渲染器来使 Gitea 呈现 Jupyter Notebooks.当然,你还可以根据本指南来为你的 Gitea 实例配置其他类型的文档渲染器,甚至是二进制文件!相信Gi ...
- Fluentd部署:错误排查
介绍一下排查Fluentd运行时错误的几种方法. 查看日志 如果感觉Fluentd运行异常,请先查看日志.td-agent安装后,默认日志存放在/var/log/td-agent/td-agent.l ...
- CentOS8本地安装Redash中文版,并且配置为生产环境
Centos8内置的Python为3.6.8版本,以下是在内置Python3.6.8基础上的安装步骤.由于安装多版本Python会导致系统底层库需要下载源码重新编译,比较麻烦,不建议在多版本Pytho ...
- TWS耳机蓝牙建连过程_HCI版本
TWS耳机信息:Enco Air2 手机信息:onePlus8 ColorOS V12.1 其他准备工作:手机进入开发者模式,打开本地日志开关.可参考上一篇文章 https://www.cnblog ...
- 驱动开发:内核R3与R0内存映射拷贝
在上一篇博文<驱动开发:内核通过PEB得到进程参数>中我们通过使用KeStackAttachProcess附加进程的方式得到了该进程的PEB结构信息,本篇文章同样需要使用进程附加功能,但这 ...
- Java代码审计之实战某博客
对某博客的代码审计 在gitee上面找了一个个人博客项目,来进行实战代码审计,主要还是学习为主 技术菜菜,哪里错误希望师傅们指正 1.SQL注入 先了解Java Web中的数据传输流程 graph T ...
- C语言整人关机程序
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char input ...
- 大文件分片上传,后端拼接保存(前端:antd;后端:.Net 5 WebAPI)
前言 对于普通业务场景而言,直接用 FormData() 将文件以入参的一个参数传给后端即可,但此方法有一个弊端就是,有个 30M 的上限. 对于动辄几百 M.几个 G 的文件上传需求,FormDat ...