题目:

题目描述

Blinker 最近喜欢上一个奇怪的游戏。
这个游戏在一个 N*M  的棋盘上玩,每个格子有一个数。每次 Blinker  会选择两个相邻的格子,并使这两个数都加上 1。
现在 Blinker 想知道最少多少次能使棋盘上的数都变成同一个数,如果永远不能变成同一个数则输出 -1。

输入格式

输入的第一行是一个整数 T,表示输入数据有T 轮游戏组成。
每轮游戏的第一行有两个整数 N 和 M , 分别代表棋盘的行数和列数。
接下来有 N 行,每行 M 个数。

输出格式

对于每个游戏输出最少能使游戏结束的次数,如果永远不能变成同一个数则输出 -1。

样例数据 1

输入  [复制]

 


2 2 
1 2 
2 3 
3 3 
1 2 3 
2 3 4 
4 3 2

输出


-1

备注

【数据范围】
对于 30% 的数据,保证 T<=10,1<=N,M<=8
对于 100% 的数据,保证 T<= 10,1<=N,M<=40,所有数为正整数且小于 1000000000

题解:

这里引用http://www.cnblogs.com/DaD3zZ-Beyonder/p/5765882.html:

一道比较有趣的题目

先对题目进行分析:

首先我们考虑对棋盘黑白染色,那么我们发现:“每次相邻两个+1”,显然是一黑一白+1

那么我们先统计出WhiteNum,BlackNum(黑白点的数目),WhiteSum,BlackSum(黑白点初始权值和)(接下来可能用Wn,Ws,Bn,Bs代替)

那么对于一次增加,显然是WhiteSum+1,BlackSum+1

考虑对最后的情况进行讨论:

那么很显然,当WhiteNum==BlackNum时(即总点数为偶数)

如果WhiteSum!=BlackSum,显然无解

如果WhiteSum==BlackSum时,我们发现,对于X如果成立,那么X+1一定成立,显然满足二分的性质,那么二分这个值,进行判定

当WhiteNum!=BlackNum时(即总点数为奇数)

发现显然,若有解,则解唯一,那么直接验证正确性即可

至于解怎么求?

设最后所有数变为X,易得X*Wn-Ws=X*Bn-Bs,整理下可得:X=(Ws-Bs)/(Wn-Bn),用网络流验证即可

那么考虑建图:

S-->白点,约束为X-val[i][j]

黑点-->T,约束为X-val[i][j]

相邻的白点-->黑点,约束为INF

判断是否满流即可

  最后说下个人心得:

  这道题的重点其实不是网络流,而是黑白染色这一想法,由相邻格子染色其实可以考虑到这一点,以后做到相似的题要注意这一想法····然后就是后面的分类讨论···也是由黑白染色后考虑答案的性质得出的·····这是一道很好的题,染色+二分+网络流;

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cctype>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int N=;
const int M=;
const long long inf=1e+;
int Ri()
{
char c;
int f=;
for(c=getchar();c<''||c>'';c=getchar());
for(;c<=''&&c>='';c=getchar())
f=(f<<)+(f<<)+c-'';
return f;
}
long long Rl()
{
char c;
long long f=;
for(c=getchar();c<''||c>'';c=getchar());
for(;c<=''&&c>='';c=getchar())
f=f*+c-'';
return f;
}
int T,n,m,tot,first[N],cur[N],lev[N],next[M],go[M],Wn,Bn,src,des;
int color[N][N],num[N][N];
long long map[N][N],rest[M],Ws,Bs,ans,sum;
inline void comb(int a,int b,long long c)
{
next[++tot]=first[a],first[a]=tot,go[tot]=b,rest[tot]=c;
next[++tot]=first[b],first[b]=tot,go[tot]=a,rest[tot]=;
}
inline bool bfs()
{
for(int i=src;i<=des;i++) cur[i]=first[i],lev[i]=-;
static int que[N],tail,u,v;
que[tail=]=src;
lev[src]=;
for(int head=;head<=tail;head++)
{
u=que[head];
for(int e=first[u];e;e=next[e])
{
if(lev[v=go[e]]==-&&rest[e])
{
lev[v]=lev[u]+;
que[++tail]=v;
if(v==des) return true;
}
}
}
return false;
}
inline long long dinic(int u,long long flow)
{
if(u==des)
return flow;
long long res=,delta;
int v;
for(int &e=cur[u];e;e=next[e])
{
if(lev[v=go[e]]>lev[u]&&rest[e])
{
delta=dinic(v,min(flow-res,rest[e]));
if(delta)
{
rest[e]-=delta;
rest[e^]+=delta;
res+=delta;
if(res==flow) break;
}
}
}
if(flow!=res) lev[u]=-;
return res;
}
inline long long maxflow()
{
long long temp=;
while(bfs())
temp+=dinic(src,inf);
return temp;
}
inline bool jud(int x,int y)
{
return x>=&&x<=n&&y>=&&y<=m;
}
inline bool check(long long lim)
{
tot=;
memset(first,,sizeof(first));
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
if(
!color[i][j])
comb(src,num[i][j],lim-map[i][j]);
else
comb(num[i][j],des,lim-map[i][j]);
}
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
if(!color[i][j])
{
if(jud(i-,j))
comb(num[i][j],num[i-][j],inf);
if(jud(i+,j))
comb(num[i][j],num[i+][j],inf);
if(jud(i,j-))
comb(num[i][j],num[i][j-],inf);
if(jud(i,j+))
comb(num[i][j],num[i][j+],inf);
}
long long temp=maxflow();
if(temp==((long long)Wn*lim-Ws))
return true;
else return false;
}
inline void solve()
{
Wn=Ws=Bn=Bs=;
src=;
des=n*m+;
int cnt=;
long long left=,right=1e+;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
num[i][j]=++cnt;
color[i][j]=(i+j)%;
if(!color[i][j])
Wn++,Ws+=map[i][j];
else
Bn++,Bs+=map[i][j];
left=max(left,map[i][j]);
}
if(Wn==Bn)
{
if(Ws!=Bs)
{
cout<<"-1"<<endl;
return;
}
else
{
while(left<=right)
{
long long mid=(left+right)/;
if(check(mid)) ans=mid,right=mid-;
else left=mid+;
}
cout<<ans*Wn-Ws<<endl;
}
}
else
{
ans=(long long)(Ws-Bs)/(Wn-Bn);
if(ans<left)
{
cout<<"-1"<<endl;
return;
} if(check(ans))
{
cout<<ans*Wn-Ws<<endl;
return;
}
else cout<<"-1"<<endl;
}
}
int main()
{
// freopen("a.in","r",stdin);
T=Ri();
while(T--)
{
n=Ri(),m=Ri();
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
map[i][j]=Rl();
solve();
}
return ;
}

刷题总结——奇怪的游戏(scoi2012)的更多相关文章

  1. C#LeetCode刷题之#55-跳跃游戏(Jump Game)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3674 访问. 给定一个非负整数数组,你最初位于数组的第一个位置. ...

  2. C#LeetCode刷题-数组

    数组篇 # 题名 刷题 通过率 难度 1 两数之和 C#LeetCode刷题之#1-两数之和(Two Sum) 43.1% 简单 4 两个排序数组的中位数 C#LeetCode刷题之#4-两个排序数组 ...

  3. 【BZOJ】【2756】【SCOI2012】奇怪的游戏

    网络流-最大流 这题……建模部分先略过 这道题是会卡时限的T_T俺的Dinic被卡了,在此放几篇很棒的讲网络流算法的文章,至于大家耳熟能详的论文就不放了…… http://www.cppblog.co ...

  4. [题目] Luogu P5038 [SCOI2012]奇怪的游戏

    学习资料 -----1----- -----2----- P5038 [SCOI2012]奇怪的游戏 一道甚神但没用到高深模型的题 思路 没思路,看题解吧 代码 #include <iostre ...

  5. BZOJ 2756: [SCOI2012]奇怪的游戏 [最大流 二分]

    2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 3352  Solved: 919[Submit][Stat ...

  6. Bzoj2756 [SCOI2012]奇怪的游戏

    2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 3220  Solved: 886 Description ...

  7. 一次失败的刷题经历:[LeetCode]292之尼姆游戏(Nim Game)(转)

    最近闲来无事刷LeetCode,发现这道题的Accept Rate还是挺高的,尝试着做了一下,结果悲剧了,把过程写下来,希望能长点记性.该题的描述翻译成中文如下: 你正在和你的朋友玩尼姆游戏(Nim ...

  8. bzoj 2756: [SCOI2012]奇怪的游戏

    Description Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数.每次 Blinker 会选择两个相邻 的格子,并使这两个数都加上 1. 现在 B ...

  9. BZOJ 2756: [SCOI2012]奇怪的游戏 网络流/二分

    2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 1594  Solved: 396[Submit][Stat ...

随机推荐

  1. Vivado增量式编译

    Vivado 中的增量设计会重新利用已有的布局布线数据来缩短运行时间,并生成可预测的结果.当设计有 95% 以上的相似度时,增量布局布线的运行时间会比一般布局布线平均缩短2倍.若相似度低于80%,则使 ...

  2. Xcode - 'openssl/opensslconf.h' file not found解决

    点击Build Settings搜索Header Search Paths,添加$(SRCROOT)/目录/Alipay

  3. sql mybatis 使用concat乱码

    先贴代码,这是sql查询里面 select id,name,sex,phone,present,adder, CONCAT("从业",experience,"年" ...

  4. Mybatis generator自动生成代码包括实体,dao,xml文件

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration ...

  5. 【转】IntelliJ 创建main函数快捷

    http://blog.csdn.net/tiantiandjava/article/details/42269173 今天偶然发现了IntelliJ中 创建main函数的快捷键,依次还有for循环, ...

  6. JDBC连接数据库详解

    JDBC连接数据库 •创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机),这通过java.la ...

  7. ios之自定义UISwitch

    系统自带的UISwitch是这样的: 既不能写字,也不能改颜色,于是在网上找到了这么一个自定义的Switch按钮,具体出处找不见了.记录一下,怕以后找不见了. 先看下效果图: 按钮的样式很多,可以文字 ...

  8. 【图论】hdu6370Werewolf

    有理有据的结论题 Problem Description "The Werewolves" is a popular card game among young people.In ...

  9. ASP.NET使用Memcached高缓存实例的初级介绍

    Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态.数据库驱动网站的速度.Memcached ...

  10. git commit 含有中文的代码,提示Warnning:Your console font probably doesn't support Unicode.......

    git 提交代码是会遇到以下问题, git commit 代码时提示: Warning: Your console font probably doesn't support Unicode. If ...