列表

详情


NC214177. 扫雷X

描述


今天是周末,冰姐和轩轩在宿舍一起玩扫雷。
扫雷的规则是这样的:在列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷。游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格。
冰姐觉得这样的规则有些无聊,便修改了非地雷格。修改后的非地雷格会显示以当前格子为中心的X区域有多少个是地雷(X的两条边会一直延伸到雷区边界)。
现在给出列的雷区中的地雷分布,要求计算出每个非地雷格以当前格子为中心的X区域的地雷个数

下图所示的非地雷格的X区域有3个地雷。


输入描述

第一行是用一个空格隔开的两个整数,分别表示雷区的行数和列数。
接下来行,每行个数字,描述了雷区中的地雷分布情况。
数字表示相应格子是地雷格,数字表示相应格子是非地雷格。

输出描述

输出包含行,每行个数字,描述整个雷区。用表示地雷格,用以非地雷格为中心X型区域的地雷个数表示非地雷格。

示例1

输入:

6 6
-1 0 -1 0 -1 -1
0 -1 0 0 -1 -1
0 -1 0 0 0 0
-1 0 -1 0 0 0
0 0 0 0 -1 0
0 0 0 -1 0 -1

输出:

-1 0 -1 3 -1 -1
2 -1 2 2 -1 -1
3 -1 5 3 2 1
-1 2 -1 5 0 3
1 4 2 2 -1 0
3 1 1 -1 2 -1

说明:

样例中非地雷格的X区域的地雷个数如下图所示

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C(clang11) 解法, 执行用时: 6ms, 内存消耗: 504K, 提交时间: 2021-02-07 10:34:00

#include <stdio.h>
	long long ch[105][105];
	long long out[105][105];
int main()
{
	int x,y,a,b;
	scanf("%d %d",&x,&y);
	for (a=0;a<x;a++){
		for (b=0;b<y;b++){
			scanf("%lld",&ch[a][b]);
		}
	}
	for (a=0;a<x;a++){
		for (b=0;b<y;b++){
			if (ch[a][b]==-1){
				int c,d;
				d=b;
				for (c=a;c<x-1;c++){
					if (d==y) break;
					out[c+1][d+1]++;
					d++;
				}
				d=b;
				for (c=a;c<x-1;c++){
					if (d==0) break;
					out[c+1][d-1]++;
					d--;
				}
				d=b;
				for (c=a;c>0;c--){
					if (d==0) break;
					out[c-1][d-1]++;
					d--;
				}
				d=b;
				for (c=a;c>0;c--){
					if (d==y) break;
					out[c-1][d+1]++;
					d++;
				}
			}
		}
	}
	for (a=0;a<x;a++){
		for (b=0;b<y-1;b++){
			if (ch[a][b]==-1) printf("-1 ");
			else printf("%lld ",out[a][b]);
		}
		if (ch[a][y-1]==-1) printf("-1\n");
		else printf("%lld\n",out[a][y-1]);
	}
}

C++(clang++11) 解法, 执行用时: 4ms, 内存消耗: 392K, 提交时间: 2020-12-06 13:44:57

#include <iostream>
#include <algorithm>
using namespace std;
int map[105][105],dx[]={1,1,-1,-1},dy[]={1,-1,1,-1};
int main()
{
	int n,m,a,b,cnt;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			scanf("%d",&map[i][j]);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(map[i][j]==0)
			{
				cnt=0;
				for(int k=0;k<4;k++)
				{
					a=i;b=j;
					while(a>0&&b>0&&a<=n&&b<=m)
					{
						a+=dx[k];b+=dy[k];
						if(a>0&&b>0&&a<=n&&b<=m&&map[a][b]==-1)cnt++;
					}
				}
				map[i][j]=cnt;
			}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
			printf("%d ",map[i][j]);
		putchar('\n');
	}
	return 0;
}

Python3(3.9) 解法, 执行用时: 335ms, 内存消耗: 3208K, 提交时间: 2020-12-06 13:29:10

from itertools import product

(n, m) = map(int, input().split())

board = []
for _ in range(n):
    row = list(map(int, input().split()))
    board.append(row)

for i in range(n):
    for j in range(m):
        if board[i][j] == -1:
            continue
        for (dir_x, dir_y) in product([-1, 1], [-1, 1]):
            for num in range(max(n, m)):
                x = i + dir_x * num
                y = j + dir_y * num
                if not (x in range(n) and y in range(m)):
                    break
                board[i][j] += (board[x][y] == -1)

for row in board:
    print(*row)

上一题