类似于扫雷游戏,在一些格子中散布着一些地雷,具体的埋藏位置并不清楚,但知道每个格子及其周围八个格子的地雷总数。请问此时正中间那一行最多可能有多少地雷(题目假定所有的输入都是奇数行的)?

输入:

   第一行,有一个正整数N,代表有N个测试数据。

   每个测试数据的第一行包含两个正整数R(行数,R是奇数)和C(列数)。以下是R行每行C列的正整数。

输出:

  每个测试数据输出一行,“Case #X: Y”,x为第几个测试数据,Y为正中间那一行最多可能有的地雷数。

 

限制条件

输入有R行C列

small

R=3,5

3≤C≤5

Large

3≤R≤49,R是奇数

3≤C≤49

 

样例1


Input
 


Output
 

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

Case #1: 1
Case #2: 1

样例1地雷的分布只有下图一种:

样例2地雷的分布只有一种:对应题目描述中的例图

 

分析:

本题从简单情况开始考虑。

1.一维的情况:

每个格子内有一个数字,但具体数字不详。但知道该格子和左右两个相邻的格子内的数字之和。

样例:

  一维格子中的数字之和:4 8 9 8 6 6 5

  一维格子中的数字:      2 2 4 3 1 2 3

那么,这时正中央格子中的数字最大是多少呢?

 2.按模3的余数分类讨论:

考虑上面的样例,把第1、第4和第7三个数加起来就可以得到所有格子的数字之和

把第2和第6二个数加起来就可以得到除正中央格子以外所有格子的数字之和。

两个结果相减,就可以推出正中央的数字为(4+8+5)-(8+6)=3

当长度模3余1时我们都可以这样计算得到正中央的数字(因为R一定为奇数,此时一定存在正中央的格子)

同样,当长度模3余2时,也可以求出两种之和,得到正中央的数字。

另一方面,当长度模3余0时,无法直接计算除正中央格子以外所有格子的数字之和。但是,可以求出重复计算了正中央的格子两次之和,再通过与全体之和相减得到正中央的数字。

3.推广到2维

 可以用前面介绍的方法求出每行及其上下两行所含的地雷总数,然后通过相减就能得到正中央那一行地雷的总数了。

4.本题的陷阱

   本题求最大值,但其实答案是唯一的。

 1 const maxn=60;
 2 var
 3   r,c,n,ans:integer;
 4   a:array[1..maxn,1..maxn] of integer;
 5   rows:array[1..maxn] of integer;
 6   procedure print(x:integer);
 7   begin
 8     writeln(x);
 9   end;
10   function solve(i:integer):integer;
11   var j,sum:integer;
12   begin
13         sum:=0;
14         if (c mod 3=1) or(c mod 3=2)  then
15         begin
16           j:=1;
17           while j<= c do begin sum:=sum+a[i,j] ;j:=j+3;end;
18         end
19         else
20         begin
21           j:=2;
22           while j<=c do begin sum:=sum+a[i,j];j:=j+3;end;
23         end;
24       solve:=sum;
25 
26   end;
27   function sol(j,m:integer):integer;
28   var sum:integer;
29   begin
30     sum:=0;
31     while j<=m do
32       begin
33         sum:=sum+rows[j] ;
34         j:=j+3;
35       end;
36    sol:=sum;
37   end;
38   function center:integer;
39   var sum:integer;
40   begin
41     if r mod 3=1 then
42     sum:=sol(1,r)-sol(2,r div 2-1)-sol(r div 2+3,r)
43     else if  r mod 3=2 then sum:=sol(2,r)-sol(1,r div 2-1)-sol(r div 2+3,r)
44     else begin
45       sum:=sol(1,r div 2 )+sol(r div 2+2,r)-sol(2,r-1);end;
46     exit(sum);
47   end;
48 
49   procedure main(r,c:integer);
50   var i :integer;
51   begin
52     for i:=1 to r do
53       begin rows[i]:=solve(i); end;
54     writeln;
55     ans:=center;
56     print(ans);
57   end;
58   procedure init;
59   var k,i,j:integer;
60   begin
61     assign(input,'mine.in');reset(input);
62     readln(n);
63     for k:=1 to n do
64       begin
65         readln(r,c);
66         for i:=1 to r do
67           for j:=1 to c do
68             begin
69               read(a[i,j]);
70             end;
71         main(r,c);
72       end;
73       close(input);
74   end;
75 begin
76   init;
77 end.
View Code