阿里面试题
题目描述
小红拿到了一个n行m列的矩阵,矩阵中用1表示人0表示聚光灯。每个聚光灯可以朝着上、下、左、右四个方向照射(照射的距离是无穷大的),若某个方向上至少有一个人,那么小红就获得了1分。
小红想知道,所有的聚光灯一共可以获得多少分?
#include<iostream>
#include<string>
#include<algorithm>
#include<bits/stdc++.h>
using namespace std;
const int maxn = 20;
int main(){
int n,m;
int ans = 0;
cin>>n>>m;
int vis[n][m];
//cout<<n<<m<<endl;
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
cin>>vis[i][j];
}
}
int left[n][m];
int right[n][m];
int up[n][m];
int down[n][m];
memset(left,0,sizeof(left));
memset(right,0,sizeof(right));
memset(up,0,sizeof(up));
memset(down,0,sizeof(down));
//左边是行的前缀和
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
if(j == 0) left[i][j] = vis[i][j];
else left[i][j] = left[i][j-1] + vis[i][j];
if(vis[i][j] == 0 && left[i][j] >= 1){
ans += 1;
}
}
}
cout << ans<<endl;
//右边是行的后缀和
for(int i=0; i<n; i++){
for(int j=m-1; j>=0; j--){
if(j == m-1) right[i][j] = vis[i][j];
else right[i][j] = right[i][j+1] + vis[i][j];
//cout << right[i][j] <<" ";
if(vis[i][j] == 0 && right[i][j] >= 1){
ans += 1;
}
}
}
cout << ans<<endl;
//上边是列的前缀和
for(int j=0; j<m; j++){
for(int i=0; i<n; i++){
if(i == 0) up[i][j] = vis[i][j];
else up[i][j] = up[i-1][j] + vis[i][j];
//cout << up[i][j] <<" ";
if(vis[i][j] == 0 && up[i][j] >= 1){
ans += 1;
}
}
}
cout << ans<<endl;
//下边是列的后缀和
for(int j=0; j<m; j++){
for(int i=n-1; i>=0; i--){
if(i == n-1) down[i][j] = vis[i][j];
else down[i][j] = down[i+1][j] + vis[i][j];
//cout << down[i][j] <<" ";
if(vis[i][j] == 0 && down[i][j] >= 1){
ans += 1;
}
}
// cout << endl;
}
cout << ans<<endl;
}