Description

Alice和Bob在玩一个游戏,给出一张n*m的棋盘,上面有一些点是障碍,游戏的开始,Alice选定棋盘上任意一个不是障碍的格子,并且将一枚棋子放在其中,然后Bob先手,两人轮流操作棋子,每次操作必须将棋子从当前位置移动到一个相邻的无障碍且未经过的格子(即每个格子不允许经过两次),不能操作的人输,如果两人都按照最有策略操作,请问初始时Alice将棋子放在哪些格子上有必胜策略。
 

Input

第一行,两个正整数n,m
接下来输入一个n*m字符矩阵,n行m列,’.’表示空的格子,‘#’表示有障碍的格子。

Output

第一行,一个正整数ans,为Alice有必胜策略的格子的个数。
接下来ans行,每行一个坐标(x,y)表示第x行第y列是一个Alice有必胜策略的初始位置,以矩阵的左上角为(1,1),右下角为(n,m)。输出位置时按照x从小到大,当x相同时y从小到大的顺序输出。

 

Sample Input

2 2
#.
..

Sample Output

2
1 2
2 1
 

Data Constraint

20%的数据: 1<=n,m<=4。
60%的数据: 1<=n,m<=10
100%的数据:1<=n,m<=100

 

Hint

如果Alice将棋子放在(1,2),Bob只能将其移动到(2,2),Alice再移动到(2,1),此时Bob无法移动,Alice获胜
如果Alice将棋子放在(2,1)号点,类似以上情况
如果Alice将棋子放在(2,2),Bob可以将棋子任意移动到(1,2)或(2,1),此时Bob获胜

Solution

由于是博弈论,可以转化成求二分图的关键点,即必然在二分图匹配中出现的点

算法要考虑染色,即当前点染黑,周围点染白,染色后把连通块都用算法匹配掉

若Alice走不在最大匹配点集内的点,则该点的周围连的一定都是匹配点,可知Bob一定走一条非匹配边到一个匹配点

由于只要先选了最大匹配点就必胜,因此在这个条件下Alice必胜

最后统计一下答案就好了

#include <stdio.h>
#include <string.h> template<class T> inline void read(T &x)
{
int c=getchar();bool b=0;
for(x=0;c<48||c>57;c=getchar())if(c==45)b=1;
for(;c>47&&c<58;c=getchar())x=(x<<1)+(x<<3)+c-48;
if(b)x=-x;
} const int N=200;
bool win[N*N];
int color[N*N],n,m,lab,num[N][N],vind,vis[N*N],lnk[N*N],Ans,fir[N*N],et=-1;
char mat[N][N]; struct Position
{
int x,y;
}pos[N*N]; struct Pointer
{
int v,next;
}e[N*N*5]; inline void link(int x,int y)
{
e[++et]=(Pointer){y,fir[x]},fir[x]=et;
e[++et]=(Pointer){x,fir[y]},fir[y]=et;
} bool dfs(int at)
{
for(int j=fir[at];~j;j=e[j].next)
if(vis[e[j].v]!=vind)
{
vis[e[j].v]=vind;
if((!lnk[e[j].v]) || dfs(lnk[e[j].v]))
{
lnk[e[j].v]=at;
return 1;
}
}
return 0;
} void find(int at)
{
for(int j=fir[at];~j;j=e[j].next)
if(lnk[e[j].v] && (!win[lnk[e[j].v]]))
{
win[lnk[e[j].v]]=1;
find(lnk[e[j].v]);
}
} int main()
{
memset(fir,-1,sizeof fir);
read(n),read(m);
for(int i=1;i<=n;i++)
scanf("%s",mat[i]+1);
lab=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(mat[i][j]=='.')
{
num[i][j]=++lab;
pos[lab].x=i;
pos[lab].y=j;
color[lab]=((i+j)&1);
if(i>1 && mat[i-1][j]=='.')
link(lab,num[i-1][j]);
if(j>1 && mat[i][j-1]=='.')
link(lab,num[i][j-1]);
}
for(int i=1;i<=lab;i++)
if(!color[i])
{
++vind;
dfs(i);
}
for(int i=1;i<=lab;i++)
if(color[i]&&lnk[i])
lnk[lnk[i]]=i;
for(int i=1;i<=lab;i++)
if(!lnk[i])
{
win[i]=1;
find(i);
}
Ans=0;
for(int i=1;i<=lab;i++)
Ans+=win[i];
printf("%d\n",Ans);
for(int i=1;i<=lab;i++)
if(win[i])
printf("%d %d\n",pos[i].x,pos[i].y);
return 0;
}

  

NOI模拟赛(3.8)Problem B的更多相关文章

  1. NOI模拟赛 Day1

    [考完试不想说话系列] 他们都会做呢QAQ 我毛线也不会呢QAQ 悲伤ING 考试问题: 1.感觉不是很清醒,有点困╯﹏╰ 2.为啥总不按照计划来!!! 3.脑洞在哪里 4.把模拟赛当作真正的比赛,紧 ...

  2. 6.28 NOI模拟赛 好题 状压dp 随机化

    算是一道比较新颖的题目 尽管好像是两年前的省选模拟赛题目.. 对于20%的分数 可以进行爆搜,对于另外20%的数据 因为k很小所以考虑上状压dp. 观察最后答案是一个连通块 从而可以发现这个连通块必然 ...

  3. NOI 模拟赛 #2

    得分非常惨惨,半个小时写的纯暴力 70 分竟然拿了 rank 1... 如果 OYJason 和 wxjor 在可能会被爆踩吧 嘤 T1 欧拉子图 给一个无向图,如果一个边集的导出子图是一个欧拉回路, ...

  4. 【2018.12.10】NOI模拟赛3

    题目 WZJ题解 大概就是全场就我写不过 $FFT$ 系列吧……自闭 T1 奶一口,下次再写不出这种 $NTT$ 裸题题目我就艹了自己 -_-||| 而且这跟我口胡的自创模拟题 $set1$ 的 $T ...

  5. NOI模拟赛Day5

    T1 有and,xor,or三种操作,每个人手中一个数,求和左边进行某一种运算的最大值,当t==2时,还需要求最大值的个数. test1 20% n<=1000 O(n^2)暴力 test2 2 ...

  6. NOI模拟赛Day4

    看到成绩的时候我的内心** woc第一题写错了呵呵呵呵呵呵呵呵 人不能太浪,会遭报应的** ------------------------------------------------------ ...

  7. NOI模拟赛Day3

    终于A题啦鼓掌~开心~ 开考看完题后,觉得第二题很好捏(傻叉上线 搞到十一点准备弃疗了然后突然发现我会做第一题 于是瞎码了码,就去准备饭票了... 好了,停止扯淡(就我一个我妹子每天不说话好难受QAQ ...

  8. NOI模拟赛Day2

    深深的感受到了自己的水 ---------------------------------------------------------------------------------------- ...

  9. 【NOI模拟赛(湖南)】DeepDarkFantasy

    DeepDarkFantasy 从东京出发,不久便到一处驿站,写道:日暮里.  ——鲁迅<藤野先生> 定义一个置换的平方为对1~n的序列做两次该置换得到的序列.已知一个置换的平方,并且这个 ...

随机推荐

  1. Luogu P1273 有限电视网【树形Dp/树形背包】

    题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节点. 从转播站到转播站以及从 ...

  2. EditextText输入类型

    android:inputType="none"--输入普通字符 android:inputType="text"--输入普通字符 android:inputT ...

  3. [Usaco2006 Jan] Dollar Dayz 奶牛商店

    Description 约翰到奶牛商场里买工具.商场里有K(1≤K≤100).种工具,价格分别为1,2,-,K美元.约翰手里有N(1≤N≤1000)美元,必须花完.那他有多少种购买的组合呢? Inpu ...

  4. _bzoj2038 [2009国家集训队]小Z的袜子(hose)【莫队】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2038 裸的莫队,注意要先移动右端点再移动左端点. #include <cstdio&g ...

  5. 递推DP UVA 473 Raucous Rockers

    题目传送门 题意:n首个按照给定顺序存在m张光盘里,每首歌有播放时间ti,并且只能完整的存在一张光盘里,问最多能存几首歌 分析:类似01背包和完全背包,每首歌可存可不存,存到下一张光盘的情况是当前存不 ...

  6. 01背包(分组) HDOJ 4341 Gold miner

    题目传送门 题意:有n个金矿,每个金矿有抓取的消耗的时间和价值,矿工在原点,问在T时间内能得到的最大的价值 分析:唯一和01背包不同的是金矿可能共线,也就是抓取近的金矿后才能抓后面共线的金矿.这是分组 ...

  7. IOS编译报错:objc-class-ref in AppDelegate.o之解决方案 Xcode7

    Undefined symbols for architecture x86_64: "_OBJC_CLASS_$_QQApiInterface", referenced from ...

  8. 1475 建设国家 DP

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1475 这题转化过来就是,给定n个点,每个点都有一个过期时间,一个价值.现 ...

  9. 移动端UI自动化Appium测试——DesiredCapabilities参数配置及含义

    一.DesiredCapabilities的作用: 负责启动服务端时的参数设置,启动session的时候是必须提供的. Desired Capabilities本质上是key value的对象,它告诉 ...

  10. AJPFX总结mysql复制表结构,表数据

    1.复制表结构及数据到新表CREATE TABLE 新表 SELECT * FROM 旧表 这种方法会将oldtable中所有的内容都拷贝过来,当然我们可以用delete from newtable; ...