最新消息: USBMI致力于为网友们分享Windows、安卓、IOS等主流手机系统相关的资讯以及评测、同时提供相关教程、应用、软件下载等服务。

地雷

IT圈 admin 22浏览 0评论

地雷

题目背景

小埋总是在家中打游戏,一天,她突然想玩Windows自带的扫雷,在一旁的哥哥看见了,想起了自己小时候信息课在机房玩扫雷的日子,便兴致勃勃地开始教小埋扫雷。然而,小埋还是不明白 \mathrm{3bv}3bv(Bechtel's Board Benchmark Value,每局将所有非雷的方块点开所需最少左键点击数,参见扫雷网的教程 )怎么算,于是她找到了你。

题目描述

小埋会告诉你一盘扫雷,用一个 n\times mn×m 的矩阵表示,11 是雷 ,00 不是雷,请你告诉她这盘扫雷的 \mathrm{3bv}3bv 。

周围八格没有“雷”且自身不是“雷”的方格称为“空格”,周围八格有“雷”且自身不是“雷”的方格称为“数字”,由“空格”组成的八连通块称为一个“空”。\mathrm{3bv}=\3bv= 周围八格没有“空格”的“数字”个数++“空"的个数。

如果看不懂上面的计算方式,可以看题目背景中给出的教程,或者看下面的样例解释。

注:八连通

输入格式

第一行有两个整数 nn 和 mm,代表这盘扫雷是一个 n \times mn×m 的矩阵。

后面的 nn 行每行有 mm 个整数,表示这个矩阵,每个数字为 00 或 11,11 代表是雷,00 代表不是雷。

输出格式

一个整数,代表这盘扫雷的 \mathrm{3bv}3bv 。

输入输出样例

输入 #1复制

8 8
0 0 0 1 1 0 0 0 
1 0 0 1 0 0 0 1 
1 0 0 1 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 1 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 1 0 0 0 0 0 0 

输出 #1复制

13

说明/提示

1\le n,\ m\le 10001≤n, m≤1000

样例解释

# include <iostream>
# include <algorithm>
# include <cstring>
# include <math.h>
# include <stdio.h>
int num[100100];
const int N = 100100;
int step[8][2] = {{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1}};
int map[1010][1010];
int mark[1010][1010];
int tot = 0;
int n,m;
using namespace std;
void put_digit(int x, int y){//通过统计所有地雷来得到旁边的数 for(int i = 0; i < 8; i++){int xx = x + step[i][0];int yy = y + step[i][1];if(xx >= 0 && xx < n && yy >= 0 && yy < m && map[xx][yy] != 9)map[xx][yy]++;} 
}
void dfs(int x, int y){//通过判断其值是否为0向外拓展来统计空白 for(int i = 0; i < 8; i++){int xx = x + step[i][0];int yy = y + step[i][1];if(xx >= 0 && xx < n && yy >= 0 && yy < m && map[xx][yy] == 0 && mark[xx][yy] == 0){mark[xx][yy] = 1;dfs(xx,yy);}}
}
int find(int x, int y){//通过判断其周围八个数字是否为0来统计 for(int i = 0; i < 8; i++){int xx = x + step[i][0];int yy = y + step[i][1];if(xx >= 0 && xx < n && yy >= 0 && yy < m && map[xx][yy] == 0)return 0;} return 1;
}
int main(){cin >> n >> m;for(int i = 0; i < n; i++){for(int j = 0; j < m; j++){cin >> map[i][j];if(map[i][j] == 1)map[i][j] = 9;}}for(int i = 0; i < n; i++){for(int j = 0; j < m; j++){if(map[i][j] == 9)put_digit(i,j);//将地雷旁边的数赋值 }}for(int i = 0; i < n; i++){for(int j = 0; j < m; j++){if(map[i][j] == 0 && mark[i][j] == 0){tot++;dfs(i,j);//统计空白数 }if(map[i][j] != 0 && map[i][j] != 9){//统计不是地雷的周围8个数不为0的数的个数 if(find(i,j) != 0){tot++;}}}}cout << tot << endl;
} 

 

地雷

题目背景

小埋总是在家中打游戏,一天,她突然想玩Windows自带的扫雷,在一旁的哥哥看见了,想起了自己小时候信息课在机房玩扫雷的日子,便兴致勃勃地开始教小埋扫雷。然而,小埋还是不明白 \mathrm{3bv}3bv(Bechtel's Board Benchmark Value,每局将所有非雷的方块点开所需最少左键点击数,参见扫雷网的教程 )怎么算,于是她找到了你。

题目描述

小埋会告诉你一盘扫雷,用一个 n\times mn×m 的矩阵表示,11 是雷 ,00 不是雷,请你告诉她这盘扫雷的 \mathrm{3bv}3bv 。

周围八格没有“雷”且自身不是“雷”的方格称为“空格”,周围八格有“雷”且自身不是“雷”的方格称为“数字”,由“空格”组成的八连通块称为一个“空”。\mathrm{3bv}=\3bv= 周围八格没有“空格”的“数字”个数++“空"的个数。

如果看不懂上面的计算方式,可以看题目背景中给出的教程,或者看下面的样例解释。

注:八连通

输入格式

第一行有两个整数 nn 和 mm,代表这盘扫雷是一个 n \times mn×m 的矩阵。

后面的 nn 行每行有 mm 个整数,表示这个矩阵,每个数字为 00 或 11,11 代表是雷,00 代表不是雷。

输出格式

一个整数,代表这盘扫雷的 \mathrm{3bv}3bv 。

输入输出样例

输入 #1复制

8 8
0 0 0 1 1 0 0 0 
1 0 0 1 0 0 0 1 
1 0 0 1 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 1 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 1 0 0 0 0 0 0 

输出 #1复制

13

说明/提示

1\le n,\ m\le 10001≤n, m≤1000

样例解释

# include <iostream>
# include <algorithm>
# include <cstring>
# include <math.h>
# include <stdio.h>
int num[100100];
const int N = 100100;
int step[8][2] = {{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1},{1,1}};
int map[1010][1010];
int mark[1010][1010];
int tot = 0;
int n,m;
using namespace std;
void put_digit(int x, int y){//通过统计所有地雷来得到旁边的数 for(int i = 0; i < 8; i++){int xx = x + step[i][0];int yy = y + step[i][1];if(xx >= 0 && xx < n && yy >= 0 && yy < m && map[xx][yy] != 9)map[xx][yy]++;} 
}
void dfs(int x, int y){//通过判断其值是否为0向外拓展来统计空白 for(int i = 0; i < 8; i++){int xx = x + step[i][0];int yy = y + step[i][1];if(xx >= 0 && xx < n && yy >= 0 && yy < m && map[xx][yy] == 0 && mark[xx][yy] == 0){mark[xx][yy] = 1;dfs(xx,yy);}}
}
int find(int x, int y){//通过判断其周围八个数字是否为0来统计 for(int i = 0; i < 8; i++){int xx = x + step[i][0];int yy = y + step[i][1];if(xx >= 0 && xx < n && yy >= 0 && yy < m && map[xx][yy] == 0)return 0;} return 1;
}
int main(){cin >> n >> m;for(int i = 0; i < n; i++){for(int j = 0; j < m; j++){cin >> map[i][j];if(map[i][j] == 1)map[i][j] = 9;}}for(int i = 0; i < n; i++){for(int j = 0; j < m; j++){if(map[i][j] == 9)put_digit(i,j);//将地雷旁边的数赋值 }}for(int i = 0; i < n; i++){for(int j = 0; j < m; j++){if(map[i][j] == 0 && mark[i][j] == 0){tot++;dfs(i,j);//统计空白数 }if(map[i][j] != 0 && map[i][j] != 9){//统计不是地雷的周围8个数不为0的数的个数 if(find(i,j) != 0){tot++;}}}}cout << tot << endl;
} 

 

发布评论

评论列表 (0)

  1. 暂无评论