题目传送门(内部题135)


输入格式

  第一行包含一个整数$T$,表示数据组数。
  对于每组数据,第一行两个整数$h,w$,表示棋盘大小。
  接下来$h$行,每行一个长度为$w$的字符串,每个位置由为$o,x,e$中一个。如果这个位置为$e$表示没有硬币,如果是$o$表示正面朝上,否则表示反面朝上。


输出格式

  共$T$行,每行一个整数表示小$M$的分数。


样例

样例输入:

1
2 5
exexe
xeoex

样例输出:

3


数据范围与提示

  $10\%$的数据,保证答案都为$0$或$1$。
  $30\%$的数据,保证答案不为$3$。
  另外$30\%$的数据,保证$h,w\leqslant 15$。
  $100\%$的数据,保证$1\leqslant T,h,w\leqslant 100$。


题解

又没有打正解……

首先,答案一定是$0,1,2,3$中的一个。

如果有一种方案能使所有面都朝上,那么答案一定不小于$2$;因为小$M$哪怕要丢掉最后的$1$分也要拿到这$2$分。

如果不能的话答案就只与$h+w$的奇偶性有关了。

那么不妨先来考虑是否可以让正面都朝上。

分为两种情况:

  $\alpha.$正面朝上,那么如果翻转行就要翻转列;如果不翻转行就一定不能翻转列。

  $\beta.$反面朝上,那么如果翻转行就不能翻转列;如果不翻转行就一定要翻转列。

用拓展域并查集维护,看最终态有没有矛盾即可。

再来考虑是否先手必胜。

分为三种情况:

  $\alpha.$如果有一个集合对应偶数次翻转,它的对立集合也对应偶数次翻转,那么不用管它。

  $\beta.$如果有一个集合对应奇数次翻转,它的对立集合也对应奇数次翻转。

  $\gamma.$如果有一个集合对应奇数次翻转,他的对立集合对应偶数次翻转。

所以我们可以只考虑后两种状态。

考虑$DP$,设$dp[i][j]$表示$\beta$状态有$i$个,$\gamma$状态有$j$个是否可行。

初始化$dp[0][0]=0$。

状态转移方程有$3$个:

  $\alpha.dp[i][j]|=!dp[i][j-1]$:选择两个奇数集合,将其变成偶数集合。

  $\beta.dp[i][j]|=!dp[i-1][j]$:选择一个奇偶面集合的奇面,将其变成偶数集合。

  $\gamma.dp[i][j]|=!dp[i-1][j+1]$:选择一个奇偶面集合的偶面,将其变成奇数集合。

这样我们就解决了这道题。

时间复杂度:$\Theta(T\times h\times w)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
int h,w;
char ch[101];
int f[401],cnt[401];
bool vis[401],dp[201][401];
void pre_work()
{
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
memset(dp,0,sizeof(dp));
}
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
void merge(int x,int y){f[find(x)]=find(y);}
bool check(){for(int i=1;i<=h+w;i++)if(find(i)==find(i+h+w))return 0;return 1;}
int judge()
{
int res1=0,res2=0;
for(int i=1;i<=h+w;i++)cnt[find(i)]++;
for(int i=1;i<=h+w;i++)
{
if(vis[find(i)])continue;
vis[find(i)]=vis[find(i+h+w)]=1;
int flag=0;
if(cnt[find(i)]&1)flag++;
if(cnt[find(i+h+w)]&1)flag++;
if(flag==1)res1++;if(flag==2)res2++;
}
for(int i=1;i<=res1+res2;i++)dp[0][i]=i&1;
for(int i=1;i<=res1;i++)
{
dp[i][0]|=(!dp[i-1][1])|(!dp[i-1][0]);
for(int j=1;j<=res1+res2;j++)
dp[i][j]|=(!dp[i-1][j+1])|(!dp[i-1][j])|(!dp[i][j-1]);
}
return dp[res1][res2];
}
int main()
{
int T;scanf("%d",&T);
while(T--)
{
pre_work();
scanf("%d%d",&h,&w);
for(int i=1;i<=((h+w)<<1);i++)f[i]=i;
for(int i=1;i<=h;i++)
{
scanf("%s",ch+1);
for(int j=1;j<=w;j++)
switch(ch[j])
{
case 'o':
merge(i,j+h);
merge(i+h+w,j+2*h+w);
break;
case 'x':
merge(i,j+2*h+w);
merge(i+h+w,j+h);
break;
}
}
if(check())printf("%d\n",judge()+2);
else printf("%d\n",(h+w)&1);
}
return 0;
}

rp++

[CSP-S模拟测试]:硬币(博弈论+DP+拓展域并查集)的更多相关文章

  1. [CSP-S模拟测试]:Dash Speed(线段树+并查集+LCA)

    题目描述 比特山是比特镇的飙车圣地.在比特山上一共有$n$个广场,编号依次为$1$到$n$,这些广场之间通过$n−1$条双向车道直接或间接地连接在一起,形成了一棵树的结构. 因为每条车道的修建时间以及 ...

  2. 【8.22校内测试】【数学】【并查集】【string】

    今天的t2t3能打出来80分的暴力都好满足啊QwQ.(%%%$idy$ 今天的签到题,做的时候一眼就看出性质叻qwq.大于11的所有数分解合数都可以用4.6.9表示,乱搞搞就可以了. #include ...

  3. POJ1417:True Liars(DP+带权并查集)

    True Liars Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  4. [CSP-S模拟测试]:B(DP+数学)

    题目传送门(内部题45) 输入格式 第一行$3$个整数$n,m,P$.第二行$m$个整数,表示$m$次询问. 输出格式 一行$m$个整数表示答案. 样例 样例输入1: 2 4 40 1 2 3 样例输 ...

  5. [CSP-S模拟测试]:蛇(DP+构造+哈希)

    题目传送门(内部题140) 输入格式 前两行有两个长度相同的字符串,描述林先森花园上的字母. 第三行一个字符串$S$. 输出格式 输出一行一个整数,表示有多少种可能的蛇,对$10^9+7$取模. 样例 ...

  6. [CSP-S模拟测试]:最小值(DP+乱搞)

    题目背景 $Maxtir$更喜欢序列的最小值. 题目传送门(内部题128) 输入格式 第一行输入一个正整数$n$和四个整数$A,B,C,D$. 第二行输入$n$个整数,第$i$个数表示$a_i$. 输 ...

  7. [CSP-S模拟测试]:花(DP)

    题目传送门(内部题111) 输入格式 一个整数$T$,表示测试数据组数. 每组测试数据占一行,两个整数,分别表示$L$和$S$. 输出格式 对每组数据,输出一个整数表示答案. 样例 样例输入1: 13 ...

  8. [CSP-S模拟测试]:计数(DP+记忆化搜索)

    题目描述 既然是萌萌哒$visit\text{_}world$的比赛,那必然会有一道计数题啦!考虑一个$N$个节点的二叉树,它的节点被标上了$1\sim N$的编号.并且,编号为$i$的节点在二叉树的 ...

  9. [CSP-S模拟测试]:matrix(DP)

    题目描述 求出满足以下条件的$n\times m$的$01$矩阵个数:(1)第$i$行第$1~l_i$列恰好有$1$个$1$.(2)第$i$行第$r_i~m$列恰好有$1$个$1$.(3)每列至多有$ ...

随机推荐

  1. mysql 相关文章

    <58到家MySQL军规升级版> <数据库索引,到底是什么做的?> <MyISAM与InnoDB的索引差异究竟是啥?> <InnoDB,为何并发如此之高?&g ...

  2. Windows 窗体消息大全(速查)

    Windows窗口消息大全,全不全自己撸 通用窗口消息 WM_NULL:--------->空消息,可检测程序是否有响应等 WM_CREATE:--------->新建一个窗口 WM_DE ...

  3. 快速幂(Fast_Power)

    定义快速幂顾名思义,就是快速算某个数的多少次幂. 其时间复杂度为 O(log2N), 与朴素的O(N)相比效率有了极大的提高. 以下以求a的b次方来介绍 原理把b转换成2进制数 该2进制数第i位的权为 ...

  4. 帝国cms 通过tags给产品或者新闻进行分类

    1.增加TAGS分类 先找到栏目== >TAGS管理 == > 管理TAGS分类 == >增加分类 2.增加相关的tag标签,也要选好TAGS分类 3.增加自定义标签模板 具体怎么写 ...

  5. 在 React 组件中使用 Refs 指南

    原文:Fullstack React's Guide to using Refs in React Components作者:Yomi Eluwande译者:博轩 译文:https://segment ...

  6. 【转载】Linux GCC常用命令

    作者:ggjucheng 出处:https://www.cnblogs.com/ggjucheng/archive/2011/12/14/2287738.html 1简介 2简单编译 2.1预处理 2 ...

  7. leetcode240 搜索二维矩阵 II

    题目: 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target.该矩阵具有以下特性: 每行的元素从左到右升序排列. 每列的元素从上到下升序排列. 示例: 现有矩阵 ma ...

  8. Delphi 文件的编程

  9. Delphi MainMenu组件

  10. 微软内部封杀 Slack

    就在 Slack 在股市上亮相之际,有一家大公司却不允许员工在日常工作中使用这款企业协作和聊天应用软件. 微软已禁止其 100000 多名员工使用免费版 Slack.IT 外媒 GeekWire 报道 ...