阿里笔试 3.14 T2

Posted 黑桃_K_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了阿里笔试 3.14 T2相关的知识,希望对你有一定的参考价值。

题目描述:
拿到一个n行m列的矩阵,矩阵种用1表示人,0表示聚光灯,每个聚光灯可以朝着上、下、左、右四个方向照射(照射的距离是无穷大的),若是一个方向上至少有一个人,那么就获得了1分。

输入描述:
第一行两个整数n, m
接下来m行,每行m个整数
用来表示矩阵中的位置是人还是聚光灯

输出描述:
输出一行,一个整数表示这些灯的分数的总和。

//输入
2 4
0 1 0 0
1 0 1 0

//输出
9
//解释
(1, 1)的灯可以获得2(向右、向下)
(1, 3)的灯可以获得2分(向左、向下)
(1, 4)的灯可以获得1分(向下)
(2, 2)的灯可以获得3分(向左、向右、向上)
(2, 4)的灯可以获得1分(向左)
总和9分。


我当时用的暴力时间复杂度比较大O(n^3)
当时的做法:
遍历每一个数,然后如果是0就进入函数(myfunc);
myfun实现的话,判断当前下标的左边、右边、上边、下边是否有1,有就++,然后break。
这里就不写了,时间复杂度那么大,最后测试用例没过完,这里就写一下好的方法吧;

dp的方法:

#include<iostream>
using namespace std;
#include<vector>

int main() 
	int n, m;
	cin >> n >> m;
	vector<vector<int>> board(n, vector<int>(m, 0));
	vector<vector<int>> uflag(n, vector<int>(m, 0));
	vector<vector<int>> rflag(n, vector<int>(m, 0));
	vector<vector<int>> lflag(n, vector<int>(m, 0));
	vector<vector<int>> dflag(n, vector<int>(m, 0));

	for (int i = 0; i < n; ++i) 
		for (int j = 0; j < m; ++j) 
			int temp = 0;
			cin >> temp;
			board[i][j]=temp;
		
	

	for (int i = 0; i < n; ++i) 
		for (int j = 0; j < m; ++j) 
			if (board[i][j] == 1)
				continue;
			if (i == 0)
				uflag[i][j] = 0;
			else
				uflag[i][j] = board[i-1][j] == 1 ? 1 : uflag[i - 1][j];

			if (j == 0)
				lflag[i][j] = 0;
			else
				lflag[i][j] = board[i][j-1] == 1 ? 1 : lflag[i][j - 1];
		
	

	for (int i = n - 1; i >= 0; --i) 
		for(int j = m - 1; j >= 0;--j)
			if (board[i][j] == 1)
				continue;
			if (i == n - 1)
				dflag[i][j] = 0;
			else
				dflag[i][j] = board[i+1][j] == 1 ? 1 : dflag[i + 1][j];
			
			if (j == m - 1)
				rflag[i][j] = 0;
			else
				rflag[i][j] = board[i][j+1] == 1 ? 1 : rflag[i][j + 1];
		 
	
	int res = 0;
	for (int i = 0; i < n; ++i) 
		for (int j = 0; j < m; ++j) 
			res += uflag[i][j] + dflag[i][j] + lflag[i][j] + rflag[i][j];
		
	
	cout << res << endl;
	return 0;


以上是关于阿里笔试 3.14 T2的主要内容,如果未能解决你的问题,请参考以下文章

阿里笔试 3.14 T1

阿里笔试 3.14 T1

2017京东笔试总结

阿里笔试——重庆阿里笔试题总结

阿里笔试——北京阿里笔试题总结

阿里前端笔试总结