题目链接 https://www.jisuanke.com/course/709/36568
题解:
用二维数组记录输入值,扫描一遍数组,用left[i]表示i行左边第一个1的列坐标,top[i]表示i列从上至下第一个1的行坐标。。
在此基础上扫描数组可以计算出结果
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
int n,m;
int res;// 结果
// 从1开始计数
int left[1010],right[1010],top[1010],down[1010];
int a[1010][1010];// 存放输入
int main() {
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i++)
for(int j = 1;j <= m;j++) {
scanf("%d",&a[i][j]);
}
// 逐行扫描
for(int i = 1;i <= n;i++) {
// i表示行
for(int j = 1;j <= m;j++) {
if(a[i][j] == 1) {
left[i] = j;break;
}
}
for(int j = m;j >= 1;j--) {
if(a[i][j] == 1) {
right[i] = j;break;
}
}
}
// 逐列扫描
for(int i = 1;i <= m;i++) {
for(int j = 1;j <= n;j++) {
if(a[j][i] == 1) {
top[i] = j;break;
}
}
for(int j = n;j >= 1;j--) {
if(a[j][i] == 1) {
down[i] = j;break;
}
}
}
for(int i = 1;i <= n;i++)
for(int j = 1;j <= m;j++) {
if(a[i][j] == 1) continue;
if(top[j] < i && top[j]!=0) res++;
if(down[j] > i && down[j]!=0) res++;
if(left[i] < j && left[i]!=0) res++;
if(right[i] > j && right[i]!=0) res++;
}
printf("%d\n",res);
return 0;
}