考拉
從前,在一片美麗的樹林裏,居住着一隻可愛的小考拉。一天,小狐狸在OJ上刷題的時候遇到了這樣一個問題:
給定一個N行M列的網格,請在每一格上填上+1或-1,使得每行和每列的數的乘積都等於-1。求方案數。
小狐狸不會做於是找到了小考拉。小考拉也不會做。你能幫助他麼?
輸入
有多組數據。輸入數據第一行包含T爲數據組數。
下面T行每行依次包含兩個整數N和M。
輸出
輸出T行每行一個整數,爲方案數。注意方案數可能很大。
樣例輸入
2
2 3
2 2
樣例輸出
0
2
數據範圍
對於20%的數據有1 ≤ N, M ≤ 5
對於100%的數據有1 ≤ N, M ≤ 100, 1 ≤ T ≤ 10
一開始就往動歸方面想。
但情況好多,於是寫了個簡單搜索程序,打了下面的表。
|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
1 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
2 |
0 |
2 |
0 |
8 |
0 |
32 |
0 |
128 |
3 |
1 |
0 |
16 |
0 |
256 |
0 |
4096 |
|
4 |
0 |
8 |
0 |
512 |
0 |
32768 |
0 |
|
5 |
1 |
0 |
256 |
0 |
66536 |
0 |
|
|
6 |
0 |
32 |
0 |
32768 |
0 |
|
|
|
7 |
1 |
0 |
4096 |
0 |
|
|
|
|
8 |
0 |
128 |
|
|
|
|
|
|
然後發現全都是2的次方,於是把錶轉化爲下面
|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
2 |
1 |
1 |
1 |
3 |
1 |
5 |
1 |
7 |
3 |
0 |
1 |
4 |
1 |
8 |
1 |
12 |
|
4 |
1 |
3 |
1 |
9 |
1 |
15 |
1 |
|
5 |
0 |
1 |
8 |
1 |
16 |
1 |
|
|
6 |
1 |
5 |
1 |
15 |
1 |
|
|
|
7 |
0 |
1 |
12 |
1 |
|
|
|
|
8 |
1 |
7 |
|
|
|
|
|
|
不難看出,對於x=y=n 則 表2[x,y] = (n-1)^2。且對於x+y=2n 的數,其值都和 表2[n,n] 有關係 。所以就有了遞歸關係式。
這題還要用到高精度。最後的結果是個非常大的數。我一開始高精度數組開100,爆了;開到1000,又爆了;直到開到5000纔沒爆。
做是做出來了,但是不知道原因。。這大概就是考試時做動歸題目的策略。
正解:
考慮前N-1行M-1列隨便填,那麼第N行的前M-1列所有位置唯一確定,第M列的前N-1行所有位置也唯一確定。
如右圖。
這時分四種情況:
若N爲奇數,M爲奇數,則區域2的格子的乘積等於負的區域1的乘積,區域3的乘積同樣等於負的區域1的乘積,而區域四的乘積等於區域2的乘積等於區域3的乘積,於是此時答案唯一。
若N爲奇數,M爲偶數,則區域2的格子的乘積等於負的區域1的乘積,區域3的乘積卻等於正的區域1的乘積,此時區域2的乘積不等於區域3的乘積,無解。
若N爲偶數,M爲偶數,同理可知解唯一。
若N爲偶數,M爲奇數,同理可知無解。
綜上可知,若N與M奇偶性相同則答案爲2(N-1)*(M-1),否則答案爲0。
var
t,n,m,k,o,key,oo,i,j:longint;
a:array[0..5000]of longint;
procedure cheng;
var
g,i:longint;
begin
g:=0;
for i:=5000 downto a[0] do
begin
a[i]:=a[i]+a[i]+g;
g:=a[i] div 10;
a[i]:=a[i] mod 10;
end;
if g<>0 then
begin
dec(a[0]);
a[a[0]]:=g;
end;
end;
begin
assign(input,'koala.in');
assign(output,'koala.out');
reset(input);
rewrite(output);
read(t);
while t>0 do
begin
dec(t);
read(n,m);
k:=m+n;
if k mod 2<>0 then
begin writeln(0); continue; end;
o:=k div 2-1;
key:=o*o;
o:=o+1;
if (o=n)or(o=m) then oo:=key
else oo:=key-abs(o-m)*abs(o-m);
fillchar(a,sizeof(a),0);
a[5000]:=1;
a[0]:=5000;
while oo>0 do
begin
cheng;
dec(oo);
end;
i:=1;
for j:=a[0] to 5000 do write(a[j]);
writeln;
end;
close(input);
close(output);
end.5