Mine Sweeper

Mine Sweeper

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Special Judge

Problem Description

A mine-sweeper map can be expressed as an r × c r×c r×c grid, and each cell of the grid is either mine cell or non-mine cell. A mine cell has no number on it, while a non-mine cell has a number, the number of mine cells that share at least one common point with the cell, on it. Following is a 16 × 30 16×30 16×30 mine-sweeper map, where flag cells denotes mine cells while blank cells denotes non-mine cells with number 0 0 0 on them.
Mine Sweeper_第1张图片

Given an integer S S S, construct a mine-sweeper map of r , c r,c r,c both not exceeding 25 25 25, whose sum of numbers on non-mine cells exactly equals S S S. If multiple solutions exist, print any one of them. If no solution, print -1 in one line.

Input

The first line contains one positive integer T ( 1 ≤ T ≤ 1001 ) T (1≤T≤1001) T(1T1001), denoting the number of test cases. For each test case:

Input one line containing one integer S ( 0 ≤ S ≤ 1000 ) S(0≤S≤1000) S(0S1000).

Output

For each test case:

If no solution, print -1 in one line.

If any solution exists, print two integers r , c ( 1 ≤ r , c ≤ 25 ) r,c(1≤r,c≤25) r,c(1r,c25) in the first line, denoting the size of the mine-sweeper map. Following r lines each contains a string only containing . or X of length c where ., X denote non-mine cells and mine cells respectively, denoting each row of the mine-sweeper map you construct.

Please notice that you needn’t print the numbers on non-mine cells since these numbers can be determined by the output mine-sweeper map.

Sample Input

2
7
128

Sample Output

2 4
X..X
X...
5 19
.XXXX..XXXXX..XXXX.
XX.......X....X..XX
X........X....XXXX.
XX.....X.X....X..XX
.XXXX...XX....XXXX.

Hint

For the first test case, the map with numbers is as follows:

X21X
X211

The sum of these numbers equals 2 + 1 + 2 + 1 + 1 = 7 2+1+2+1+1=7 2+1+2+1+1=7.

思路

  1. 如果 S ≤ 24 S≤24 S24,我们可以构造这样的地图:" . X . X . X ⋯ .X.X.X\cdots .X.X.X",可知当长度为 l l l 的时候,数字和就等于 l − 1 l - 1 l1
  2. 如果 S > 24 S > 24 S>24,我们可以把 S S S 写成 S = 8 a + 3 b S = 8a + 3b S=8a+3b 的形式,其中 a , b > 0 ; b < 8 a,b >0; b < 8 a,b>0;b<8 ( g c d ( a , b ) = 1 那 么 不 能 组 成 最 大 的 数 为 a ∗ b − a − b ) (gcd(a,b)=1那么不能组成最大的数为a*b-a-b) (gcd(a,b)=1abab)那么我们可以构造类
    似如下的地图:
. . . . . . . . .
. X . X . X . X .
. . . . . . . . .
. X . X . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . X X

其中包含恰好 a a a 个孤立的 X b b b 个右下角那种连续的 X,可知一个孤立的X 可以对数字和 带来 8 8 8 的贡献,而右下角那种连续的X一个可以带来 3 3 3 的贡献。

/***  Amber  ***/
#pragma GCC optimize(3,"Ofast","inline")
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define ls (rt<<1)
#define rs (rt<<1|1)
typedef long long ll;
template <typename T>
inline void read(T &x) {
    x = 0;
    static int p;
    p = 1;
    static char c;
    c = getchar();
    while (!isdigit(c)) {
        if (c == '-')p = -1;
        c = getchar();
    }
    while (isdigit(c)) {
        x = (x << 1) + (x << 3) + (c - 48);
        c = getchar();
    }
    x *= p;
}
template <typename T>
inline void print(T x) {
    if (x<0) {
        x = -x;
        putchar('-');
    }
    static int cnt;
    static int a[50];
    cnt = 0;
    do {
        a[++cnt] = x % 10;
        x /= 10;
    } while (x);
    for (int i = cnt; i >= 1; i--)putchar(a[i] + '0');
    puts("");
}
const double pi=acos(-1);
const double eps=1e-6;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const int maxn = 10010;
int S;
inline void work() {
    read(S);
    if (S < 24) {
        printf("1 %d\n", S + 1);
        if (S & 1) {
            for (int i = 1; i <= S / 2 + 1; i++) {
                printf(".X");
            }
        } else {
            for (int i = 1; i <= S / 2; i++) {
                printf(".X");
            }
            putchar('.');
        }
        puts("");
        return;
    }
    int a = S / 8, b = 0;
    while (1) {
        if ((S - a * 8) % 3 == 0) {
            b = (S - a * 8) / 3;
            break;
        }
        a--;
    }
    printf("25 25\n");
    for (int i = 1; i < 25; i++) {
        if (i & 1) {
            for (int j = 1; j <= 25; j++) {
                putchar('.');
            }
        } else {
            for (int j = 1; j <= 25; j++) {
                if (j % 2 == 0 && a > 0) {
                    putchar('X');
                    a--;
                } else putchar('.');
            }
        }
        puts("");
    }
    for (int i = 1; i <= 25; i++) {
        if (i > 25 - b) putchar('X'); else putchar('.');
    }
    puts("");
}
int main() {
    //freopen("1.txt","r",stdin);
    int T = 1;
    read(T);
    while (T--) {
        work();
    }
    return 0;
}

你可能感兴趣的:(构造,acm竞赛)