题目大意
给定一个N*M的棋盘,每个格子里最多只可以放置一个棋子,求有多少种放置方案使得任意2*2的正方形区域内恰有2个棋子。
数据规模
对于30%的数据 N,M<=20
对于100%的数据 N,M<=10000
题解:
找规律+高精度:
答案就是2^M+2^N-2
公式推理:
首先我们对于这题,可以分析一下发现,
只要任意2行确定了任意2列确定了,那么整个矩形必定被确定下来了,此时就是一种方案数。
那么任意两列与任意两行共有多少种放法呢?
我们继续推:
假如就是前2行前2列:
对于前2行,我们发现取一列出来看一下:
1为放棋/0为不放
对于一组
0
1
我们如果要在它后面填棋子并且要满足,就必须要是
1 ···· 0
0 亦或者是 1,
对于一组
1
0
也是同理,所以填满前2行有2^M方式,但是因为
对于一种情况
0 0
1 1
这时候你必定就会有2列被固定,因为方案就被固定了,
而仅有
1 0 1 …… ·· 0 1 0
0 1 0 …… 或者 1 0 1不会被固定
所以此时被固定的方案有2^M-2种
然后我们单独考虑上述2种情况,
而你现在对于前2列,3到n行并不确定,
考虑0 1 或 1 0下面可以有2^(n-2)种放法,
因为有0 1 跟 1 0两种 所以有2^(n-1)种
因为有2个0 1 跟 2个1 0 所以有2^N种
因此,公式就是2^N+2^M-2
而因为数据所以套一下高精度就可以了。
如果你想优美那么你可以试试压位~
代码:
const
maxn=10000;
var
a,b,c:array [0..maxn+1] of longint;
lena,lenb,lenc,i,j,x,n,m:longint;
begin
assign(input,'chess.in'); reset(input);
assign(output,'chess.out'); rewrite(output);
readln(n,m);
lena:=1;
a[1]:=1;
for i:=1 to n do
begin
x:=0;
for j:=1 to lena do
begin
a[j]:=a[j]*2+x;
x:=a[j] div 10;
a[j]:=a[j] mod 10;
end;
a[lena+1]:=x;
if a[lena+1]>0 then inc(lena);
end;
lenb:=1;
b[1]:=1;
for i:=1 to m do
begin
x:=0;
for j:=1 to lenb do
begin
b[j]:=b[j]*2+x;
x:=b[j] div 10;
b[j]:=b[j] mod 10;
end;
b[lenb+1]:=x;
if b[lenb+1]>0 then inc(lenb);
end;
a[1]:=a[1]-2;
i:=1; x:=0;
while (i<=lena) or (i<=lenb) do
begin
c[i]:=a[i]+b[i]+x;
x:=c[i] div 10;
c[i]:=c[i] mod 10;
i:=i+1;
end;
if x>0 then
begin
lenc:=i;
c[i]:=x;
end
else lenc:=i-1;
for i:=lenc downto 1 do write(c[i]);
close(input); close(output);
end.