UESTC 653 扫雷 模拟

扫雷

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
Submit  Status

扫雷是一种常见的游戏。现在我们想改变一下扫雷的规则。

n×n 的方格地图上,地雷可以影响所有曼哈顿距离不大于 k 的位置,现在给出地图中雷的分布,用*代表地雷,用.代表无雷,请在所有无雷的

位置填上对应的数字,表示能够影响到该位置的雷的数量。

在平面上,坐标 (x1,y1)   的点 P1 与坐标 (x2,y2)   的点 P2 的曼哈顿距离为:

|x1x2|+|y1y2|

Input

第一行是一个整数 T ( T10 )表示数据组数。

每组数据第一行包含两个数字 n k n 不大于 20 k 不大于 20 ;

接下来包含 n 行,每行 n 个字符

*代表地雷,.代表无雷,字符中间不含空格。

Output

对于每组数据,输出相应的分布图,有雷的位置输出 1 ,无雷的位置输出对应的数字,每行的相邻两个数用一个空格隔开(每行的最后请不要输出多余

的空格)。

Sample input and output

Sample Input Sample Output
2
2 1
*.
..
3 2
*..
...
*..
-1 1
1 0
-1 1 1
2 2 0
-1 1 1

My Solution

建ch[maxn][maxn]放字符分布图,ci[maxn][maxn]放数字分布图;
然后就是遇到一个*就来一次对角线正交的字符型,就是菱形的感觉。然后开始扫,把4个方向可以简化为1个方向,且对起始点要特别注意,
且很可能是被切过几刀的图像,所以要随时检查边界;
终止点就用|i-x|+|j-y|<=k又因为把四个象限简化到第一象限了,所以用i-x+j-y<=k就好了,
然后,模拟吧。(应该有其它方法的☺☺)

#include <iostream>
#include <cstdio>
#include <cstring>
//#define LOCAL
using namespace std;
const int maxn=22;
char ch[maxn][maxn];
int ci[maxn][maxn],k,n;
//本来想把左右扫并一起,上下扫并一起   但整个的菱形不一定全在,就不对称了,分开扫又太慢了,对if里面加个条件
inline void solve(int x,int y)
{
    for(int i=x;i<=x+k;i++){
        if(i==x){
            for(int j=y+1;(i-x+j-y<=k);j++){
                if((ch[j][i]!='*')&&(j<n&&j>=0&&i>=0&&i<n)) ci[j][i]++;
                if((ch[2*y-j][i]!='*')&&(2*y-j<n&&2*y-j>=0&&i>=0&&i<n)) ci[2*y-j][i]++;
            }
        }
        else{
            if((ch[y][i]!='*')&&i>=0&&i<n)ci[y][i]++;if((ch[y][2*x-i]!='*')&&2*x-i>=0&&2*x-i<n)ci[y][2*x-i]++;
            for(int j=y+1;(i-x+j-y<=k);j++){
                if((ch[j][i]!='*')&&(j<n&&j>=0&&i>=0&&i<n)) ci[j][i]++;
                if((ch[2*y-j][i]!='*')&&(2*y-j<n&&2*y-j>=0&&i>=0&&i<n)) ci[2*y-j][i]++;
                if((ch[j][2*x-i]!='*')&&(2*x-i<n&&2*x-i>=0&&j<n&&j>=0)) ci[j][2*x-i]++;
                //if((ch[j][2*x-i]!='*')&&(2*x-i<n&&2*x-i>=0&&j<n&&j>=0)) ci[j][2*x-1]++;这个地方i写成1了,太不小心了
                if((ch[2*y-j][2*x-i]!='*')&&(2*y-j<n&&2*y-j>=0&&2*x-i<n&&2*x-i>=0)) ci[2*y-j][2*x-i]++;
            }
        }
    }
}

int main()
{
    #ifdef LOCAL
    freopen("a.txt","r",stdin);
    #endif // LOCAL
    int T;
    scanf("%d",&T);
    while(T--){
        memset(ci,0,sizeof(ci));
        scanf("%d%d",&n,&k);
        for(int i=0;i<n;i++)
            scanf("%s",ch[i]);
        for(int j=0;j<n;j++)
            for(int i=0;i<n;i++)
                if(ch[i][j]=='*'){
                    ci[i][j]=-1;
                    solve(j,i);
/*
                    前面总是WA,所以自己造了组数据,还好一组数据就找出问题了
                    1
                    6 4
                    *.....
                    ......
                    ......
                    ...**.
                    ....*.
                    *.....
                    当时出了个'6',明明只有五个雷。所以把每次solve()完都把矩阵输出看看,
                    反正下面有写,贴上来就好了

                    for(int i=0;i<n;i++){
                        printf("%d",ci[i][0]);
                        for(int j=1;j<n;j++)
                            printf(" %d",ci[i][j]);
                        printf("\n");
                    }printf("\n");
*/
                }
        for(int i=0;i<n;i++){
            printf("%d",ci[i][0]);
            for(int j=1;j<n;j++)
                printf(" %d",ci[i][j]);
            if(i!=n-1)printf("\n");
        }
        if(T) printf("\n");
    }
    return 0;
}

谢谢

你可能感兴趣的:(UESTC 653 扫雷 模拟)