Mine Layer(2008 World Final C)数学问题+降维

来自《挑战程序设计竞赛》

1.题目原文

https://code.google.com/codejam/contest/32011/dashboard#s=p2

Problem

MineLayer is a MineSweeper-like puzzle game played on an R by C grid. Each square in the grid either has one mine or no mines at all. A MineLayer puzzle consists of a grid of numbers, each of which indicates the total number of mines in all adjacent squares and in the square underneath. The numbers will thus range from zero to nine.

The objective of MineLayer is to figure out a layout of the mines in the grid that matches the given clues.

Below is a typical 3 by 4 grid. The original layout is on the left, and the puzzle on the right.

Since there may be many solutions, your task is to write a program that outputs the maximum possible number of mines in the middle row. The number of rows will always be odd, and there will always be at least one solution to the puzzle.

Input

The first line of input gives the number of cases, NN test cases follow.

The first line of each case contains two space-separated numbers: R, the number of rows, and C, the number of columns. R is always an odd integer. Each of the next R lines contains C space-separated numbers that denote the clues of that row.

Output

For each test case, output one line containing "Case #X: Y", where X is the 1-based case number, and Y is the maximum possible number of mines in the middle row of a grid that satisfies the given constraints.

Limits

1 ≤ N ≤ 50.
Each puzzle is guaranteed to have at least one solution.

Small dataset

R = 3 or R = 5.
3 ≤ C ≤ 5.

Large dataset

R is an odd number between 3 and 49, inclusive.
3 ≤ C ≤ 49.

Sample


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

2.解题思路

先从简化版的一维版问题考虑。每个格子有一个数字,但是不知道。只知道该格子和相邻格子的总和。
按照模3的余数分类讨论,即可解决。详情见代码。
接下来拓展到二维。只要先用前面的方法对各行求出全体之和,我们就可以得知每行及其上下行所含的地雷总数。然后再对各行的全体之和运用一维版问题的方法,就可以求出正中央那一行的地雷的个数了。
本题要求最大值,但是值是唯一的,这是本题设置的最大陷阱。

3.AC代码

#include
#include
#include
#include
#include
#include
#include
using namespace std;

#define MAX_RC 50
int R,C;
int A[MAX_RC][MAX_RC];

//计算长度为n的一维版问题的总和
int total(int *a,int n)
{
    int res=0;
    //按模3的余数讨论
    if(n%3==1||n%3==2){
        for(int i=0;i


你可能感兴趣的:(数学问题,GCJ,挑战程序设计竞赛,Mine,Layer2008,World,GCJ,挑战程序设计竞赛)