bzoj2756 SCOI2012 奇怪的遊戲

2021-07-11 05:16:48 字數 2780 閱讀 5668

description

blinker最近喜歡上乙個奇怪的遊戲。

這個遊戲在乙個 n*m 的棋盤上玩,每個格仔有乙個數。每次 blinker 會選擇兩個相鄰

的格仔,並使這兩個數都加上 1。

現在 blinker 想知道最少多少次能使棋盤上的數都變成同乙個數,如果永遠不能變成同

乙個數則輸出-1。

input

輸入的第一行是乙個整數t,表示輸入資料有t輪遊戲組成。

每輪遊戲的第一行有兩個整數n和m, 分別代表棋盤的行數和列數。

接下來有n行,每行 m個數。

output

對於每個遊戲輸出最少能使遊戲結束的次數,如果永遠不能變成同乙個數則輸出-1。

sample input

2 2 2

1 2

2 3

3 3

1 2 3

2 3 4

4 3 2

sample output

2 -1

hint

【資料範圍】

對於30%的資料,保證  t<=10,1<=n,m<=8
對於100%的資料,保證 t<=10,1<=n,m<=40,所有數為正整數且小於1000000000

source

cxjyxx_me:

blinker最近喜歡上乙個奇怪的遊戲。

這個遊戲在乙個 n*m 的棋盤上玩,每個格仔有乙個數。每次 blinker 會選擇兩個相鄰

的格仔,並使這兩個數都加上 1。

現在 blinker 想知道最少多少次能使棋盤上的數都變成同乙個數,如果永遠不能變成同

乙個數則輸出-1。

對棋盤進行黑白染色

設黑格個數為num1 數值和為sum1

設白格個數為num1 數值和為sum1

設最後都變為x

則 num1 * x – sum1 = num2 * x – sum2

x = (sum1 – sum2) / (num1 – num2)

當num1 ≠ num2時 可以解出 x 再用網路流check即可

對於num1 = num2時 可以發現 對於乙個合法的x k>=x都是乙個合法的解

因為num1 = num2 => (num1 + num2) % 2 == 0 可以構造一層的滿覆蓋

所以可以二分x 然後用網路流check

建圖:

如果點k為白

建邊(s, k, x – v[k])

如果為黑

建邊(k, t, x – v[k])

對相鄰點u、v (u為白)

建邊 (u, v, inf)

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define m 20005

#define inf (1ll<<50)

#define pa pair

#define ll long long

#define p(x,y) (x-1)*m+y

using namespace std;

inline int

read()

while (ch >= '0' && ch <= '9')

return

x * f;

}ll s

0,s1;

int c0,c1;

int test,n,m,cnt,s,t;

int xx[4] = ;

int yy[4] = ;

int a[45][45];

int head[2005],h[2005],q[2005],cur[2005];

bool color[45][45];

struct edge

e[20005];

void ins(int u, int v, ll w)

void insert(int u, int v, ll w)

ll dfs(int

x, ll f)

}if(used == 0) h[x] = -1;

return used;

}int bfs()}}

if(h[t] == -1) return

0; else

return1;}

ll dinic()

return ans;

}bool check(ll x)

}else insert(p(i, j), t, x - a[i][j]);

if(dinic() == tot)return

1; return0;}

int main()

for(int i = 1; i <= n; i ++)

for(int j = 1; j <= m; j ++)

if(color[i][j]) s1 += a[i][j], c1 ++;

else

s0 += a[i][j], c0 ++;

if(c0 != c1)

puts("-1");

}else

printf("%lld\n",(ll)l * c1 - s1);

}}

return

0;}

bzoj2756 SCOI2012 奇怪的遊戲

description blinker最近喜歡上乙個奇怪的遊戲。這個遊戲在乙個 n m 的棋盤上玩,每個格仔有乙個數。每次 blinker 會選擇兩個相鄰的格仔,並使這兩個數都加上 1。現在 blinker 想知道最少多少次能使棋盤上的數都變成同乙個數,如果永遠不能變成同乙個數則輸出 1。input...

bzoj2756 SCOI2012 奇怪的遊戲

blinker最近喜歡上乙個奇怪的遊戲。這個遊戲在乙個 n m 的棋盤上玩,每個格仔有乙個數。每次 blinker 會選擇兩個相鄰的格仔,並使這兩個數都加上 1。現在 blinker 想知道最少多少次能使棋盤上的數都變成同乙個數,如果永遠不能變成同乙個數則輸出 1。輸入的第一行是乙個整數t,表示輸入...

bzoj2756 SCOI2012 奇怪的遊戲

傳送門 思路 先黑白染色,設白格個數為cnt0,和為sum0,黑格個數為cnt1,和為sum1,假設最後所有點都變成了x 那麼如果cnt0 cnt1就是格仔數為奇數時 cnt0 x sum0 cnt1 x sum1 x sum0 sum1 cnt0 cnt1 格仔為偶數時x沒有意義 我們就要想新的方...