问题 B: 不爱学习的小W
时间限制: 2 Sec 内存限制: 64 MB
题目描述
“叮铃铃”上课了,同学们都及时到了教室坐到了座位上,教室里有n行m列的座位而且刚好坐满。既然是上课,那老师叫学生回答问题就是再正常不过的事了,同样地,教室里也就有爱学习和不爱学习的学生了,爱学习的学生对老师提的问题都知道,而不爱学习的学生却恰好相反,对老师提的问题都不知道。爱学习的同学对别人的求助都会热情地伸以援手。
小W也在这个教室上课,但是这个时候小W却很紧张,为什么呢,因为小W就是个不爱学习的学生,对老师提的问题一个都不知道,而且这个任课老师每节课上都点名,且每次点名都是随机的。本来如果点到他他也会想尽办法求助前后左右直接相邻的同学(远了就无能为力了啊),问题就是,他前后左右都是不爱学习的同学, 所以这个时候他特别地紧张,担心下一个点到的就是自己。
同样,其他不爱学习的同学如果被点到也只能求助前后左右直接相邻的同学,要是相邻同学都不爱学习,那也会和小W一样紧张了。当然爱学习的同学肯定就不紧张啦。所以小W想知道,这节课有多少个和自己一样也在紧张的同学(当然小W自己也在紧张咯)。
输入
输入包括多组数据(组数不超过50)。每组数据格式如下:
第一行两个正整数n和m,n * m <= 1000000。
接着是n行m列个数,只包含0和1,0代表该位置的学生不爱学习,1代表该位置的学生爱学习。
输出
对于每组数据,输出一个数,代表这节课上紧张的学生人数,保证答案大于零。
样例输入
2 3
0 0 0
0 0 0
3 4
1 0 1 1
0 0 0 1
1 0 1 1
样例输出
6
1
思路
n * m <= 1000000 这个条件导致我们不能使用二维数组,所以我们用一维
一维下标 [ i ] ,二维下标 [ ( i / n ) - 1 ][ ( i % n) - 1 ]
二维下标 [ i ][ j ] , 一维下标 [ ( i - 1 ) * n + ( j - 1)]
我们可以让爱学习的同学附近不爱学习的同学变为 -1
这样遍历一次之后 为 0 的 同学 就是 紧张的同学
#include <iostream>
#include <cstdio>
#define MAXN 1000005
using namespace std;
int b[4][2] = {0,1,-1,0,1,0,0,-1};
int a[MAXN];
int main(){
int n,m;
while (scanf("%d %d",&n,&m) != EOF) {
int count = 0 ;
int cnt = 0 ;
for (int i = 0 ; i < n ; i++) {
for (int j = 0 ; j < m ; j++) {
scanf("%d",&a[cnt++]);
}
}
for (int i = 0 ; i < cnt ; i++) {
//一维下标 转为 二维下标
int x=i/m+1,y=i%m+1;
if (a[i] == 1) {
for (int j = 0 ; j < 4 ; j++) {
int X = x + b[j][0] ;
int Y = y + b[j][1] ;
if (X < 1 || X > n || Y < 1 || Y > m) {
} else {
//二维下标 转为 一维下标
int k=(X-1)*m+(Y-1) ;
if (a[k] != 1) {
a[k] = -1 ;
}
}
}
}
}
for (int i = 0 ; i < cnt ; i++) {
if (a[i] == 1 || a[i] == -1) {
count++;
}
}
printf("%d\n",n*m-count);
}
return 0;
}
/**************************************************************
Problem: 1881
User: 21XXXXXXXX
Language: C++
Result: 正确
Time:446 ms
Memory:5928 kb
****************************************************************/