刷题总结——奇怪的游戏(scoi2012)
题目:
题目描述
Blinker 最近喜欢上一个奇怪的游戏。
这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数。每次 Blinker 会选择两个相邻的格子,并使这两个数都加上 1。
现在 Blinker 想知道最少多少次能使棋盘上的数都变成同一个数,如果永远不能变成同一个数则输出 -1。
输入格式
输入的第一行是一个整数 T,表示输入数据有T 轮游戏组成。
每轮游戏的第一行有两个整数 N 和 M , 分别代表棋盘的行数和列数。
接下来有 N 行,每行 M 个数。
输出格式
对于每个游戏输出最少能使游戏结束的次数,如果永远不能变成同一个数则输出 -1。
样例数据 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)的更多相关文章
- C#LeetCode刷题之#55-跳跃游戏(Jump Game)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3674 访问. 给定一个非负整数数组,你最初位于数组的第一个位置. ...
- C#LeetCode刷题-数组
数组篇 # 题名 刷题 通过率 难度 1 两数之和 C#LeetCode刷题之#1-两数之和(Two Sum) 43.1% 简单 4 两个排序数组的中位数 C#LeetCode刷题之#4-两个排序数组 ...
- 【BZOJ】【2756】【SCOI2012】奇怪的游戏
网络流-最大流 这题……建模部分先略过 这道题是会卡时限的T_T俺的Dinic被卡了,在此放几篇很棒的讲网络流算法的文章,至于大家耳熟能详的论文就不放了…… http://www.cppblog.co ...
- [题目] Luogu P5038 [SCOI2012]奇怪的游戏
学习资料 -----1----- -----2----- P5038 [SCOI2012]奇怪的游戏 一道甚神但没用到高深模型的题 思路 没思路,看题解吧 代码 #include <iostre ...
- BZOJ 2756: [SCOI2012]奇怪的游戏 [最大流 二分]
2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 3352 Solved: 919[Submit][Stat ...
- Bzoj2756 [SCOI2012]奇怪的游戏
2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 3220 Solved: 886 Description ...
- 一次失败的刷题经历:[LeetCode]292之尼姆游戏(Nim Game)(转)
最近闲来无事刷LeetCode,发现这道题的Accept Rate还是挺高的,尝试着做了一下,结果悲剧了,把过程写下来,希望能长点记性.该题的描述翻译成中文如下: 你正在和你的朋友玩尼姆游戏(Nim ...
- bzoj 2756: [SCOI2012]奇怪的游戏
Description Blinker最近喜欢上一个奇怪的游戏. 这个游戏在一个 N*M 的棋盘上玩,每个格子有一个数.每次 Blinker 会选择两个相邻 的格子,并使这两个数都加上 1. 现在 B ...
- BZOJ 2756: [SCOI2012]奇怪的游戏 网络流/二分
2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 1594 Solved: 396[Submit][Stat ...
随机推荐
- vs2010调试sql2008存储过程
1.安装vs2010sp1补丁 2.vs中打开服务器资源管理器,并进行数据库连接,连接时要注意 3. 4.可以打开数据库中的存储过程进行调试了
- js 分组数组
思路: 1.先将数组按照一定规则排序: 2.再拆分数组到Map中,按Key分类: 3.再从Map中遍历取出要显示的内容: sortBroadList: function (broadcastList) ...
- 从汇编看c++中临时对象的析构时机
http://www.cnblogs.com/chaoguo1234/archive/2013/05/12/3074425.html c++中,临时对象一旦不需要,就会调用析构函数,释放其占有的资源: ...
- webpack devserver的说明
一般我们在项目中 如果用webpack的话,基本都会用到webpack-dev-server,配置大致如下: devServer={ contentBase: basePath, historyApi ...
- 伪题解 洛谷 P1363 幻想迷宫(DFS)
毒瘤题,做了一晚上抄题解A了 因为是抄题解,我也不好意思说什么了,就发篇博客纪念一下吧 #include<iostream> #include<cstring> #includ ...
- javaEE(7)_自定义标签&JSTL标签(JSP Standard Tag Library)
一.自定义标签简介 1.自定义标签主要用于移除Jsp页面中的java代码,jsp禁止出现一行java脚本. 2.使用自定义标签移除jsp页面中的java代码,只需要完成以下两个步骤: •编写一个实现T ...
- 使用CSS来制作类似「黑幕」的效果
网上几乎没有看到这类的代码,留个档 .heimu,.heimu a{ background-color: #252525; color:#252525; text-shadow: none; }::s ...
- iptables(1)工具详解
一. iptables 查看链表,创建链表,类命令 1. iptables [-t table] -N chain : 创建一条自定义规则的链 1 2 # iptables -t filter ...
- Python9-面对对象1-day22
def Person(name,blood,aggr,sex): person = { 'name' : name, 'blood':blood, 'aggr': aggr, 'sex' : sex, ...
- LCD驱动分析(一)字符设备驱动框架分析
参考:S3C2440 LCD驱动(FrameBuffer)实例开发<一> S3C2440 LCD驱动(FrameBuffer)实例开发<二> LCD驱动也是字符设备驱动,也 ...