牛客网OJ题解--20210208
岛屿数量
https://www.nowcoder.com/questionTerminal/0c9664d1554e466aa107d899418e814e
本系列记录翀翀😐痛苦的刷题日志,所有题目均来自于牛客网OJ题目,坚持刷题谈起来容易做起来难,希望我可以坚持下去,这里仍然分享一段励志文案:每个人都有梦想,然而有些人把梦想变成了现实,有些人的梦想依旧是梦想,只因为他们为梦想付出的努力程度不一样,他们坚持的时间不一样,最终才有这样的结果。
NC109-岛屿数量
题目链接
https://www.nowcoder.com/questionTerminal/0c9664d1554e466aa107d899418e814e
题目描述
给一个01矩阵,1代表是陆地,0代表海洋, 如果两个1相邻,那么这两个1属于同一个岛。我们只考虑上下左右为相邻。岛屿: 相邻陆地可以组成一个岛屿(相邻:上下左右) 判断岛屿个数。
测试样例
输入
[[1,1,0,0,0],[0,1,0,1,1],[0,0,0,1,1],[0,0,0,0,0],[0,0,1,1,1]]
输出
3
解题思路
dfs,从为1大陆块为起点,一直沿着1走,顺便把走过的标记为0,这样就可以防止再次重复走过这个大陆,每次走完一次知道不能在走了说明走完一个岛屿,增加岛屿数量。
解题代码
class Solution
{
public:
/**
* 判断岛屿数量
* @param grid char字符型vector<vector<>>
* @return int整型
*/
int m, n;
//地图
int Map[205][205];
//四个方向向量
int dir[4][2] = {{0, 1}, {0, -1}, {-1, 0}, {1, 0}};
void dfs(int x, int y)
{
//越界了就停止
if (x < 0 || x >= m || y < 0 || y >= n || Map[x][y] == 0)
{
return;
}
//走过的大陆标记为0,防止再次走过
if (Map[x][y] == 1)
Map[x][y] = 0;
//四个方向均再次尝试
for (int i = 0; i < 4; i++)
{
dfs(x + dir[i][0], y + dir[i][1]);
}
}
int solve(vector<vector<char>> &grid)
{
//m行n列
m=grid.size();
n = grid[0].size();
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
//因为给的是字符,所以要转换成整型
Map[i][j] = grid[i][j]-'0';
}
}
// for(int i=0;i<m;++i){
// for(int j=0;j<n;++j)
// cout<<Map[i][j];
// cout<<endl;
// }
//岛屿数量初始化为0
int num=0;
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
//当时大陆时,可以作为起点
if (Map[i][j] == 1)
{
//必定走完一个道岛
dfs(i, j);
//增加岛的数量
num++;
}
}
}
return num;
}
}; NC20035-打鼹鼠
题目链接
https://ac.nowcoder.com/acm/problem/20035
题目描述
鼹鼠是一种很喜欢挖洞的动物,但每过一定的时间,它还是喜欢把头探出到地面上来透透气的。根据这个特点阿Q编写了一个打鼹鼠的游戏:在一个n*n的网格中,在某些时刻鼹鼠会在某一个网格探出头来透透气。 你可以控制一个机器人来打鼹鼠,如果i时刻鼹鼠在某个网格中出现,而机器人也处于同一网格的话,那么这个鼹鼠就会被机器人打死。而机器人每一时刻只能够移动一格或停留在原地不动。 机器人的移动是指从当前所处的网格移向相邻的网格,即从坐标为(i,j)的网格移向(i-1, j),(i+1, j),(i,j-1),(i,j+1)四个网格,机器人不能走出整个n*n的网格。游戏开始时,你可以自由选定机器人的初始位置。 现在你知道在一段时间内,鼹鼠出现的时间和地点,希望你编写一个程序使机器人在这一段时间内打死尽可能多的鼹鼠。
第一行为n(n ≤ 1000), m(m ≤ 10000),其中m表示在这一段时间内出现的鼹鼠的个数,
接下来的m行每行有三个数据time,x,y表示有一只鼹鼠在游戏开始后time个时刻,在第x行第y个网格里出现了一只鼹鼠。
Time按递增的顺序给出。注意同一时刻可能出现多只鼹鼠,但同一时刻同一地点只可能出现一只鼹鼠。
测试样例
输入
2 2 1 1 1 2 2 2
输出
1
解题思路
这道题一开始想使用bfs来做,但是超时严重,并且难以存储,后来查看题解后才知道是使用dp来做,因为时间给的是默认递增排序。我们声明dp[i]表示为在抓到第i只小鼠时最多之前能抓到多少只小鼠。所以
dp[j]是上一只抓到的小鼠。所以一开始就将所有的dp[i]初始化为1即都原地守株待兔必定可以抓到一只。又因为此题涉及到了能否到达的问题,所以需要满足曼哈顿距离小于等于时间差才可以。
解题代码
#include <bits/stdc++.h>
using namespace std;
int dp[10005], n, m, _time[10005], _x[10005], _y[10005], ans; //dp[i]表示到第i只时能打多少只
int main()
{
cin >> n >> m;
for (int i = 1; i <= m; i++)
{
cin >> _time[i] >> _x[i] >> _y[i];
}
for (int i = 1; i <= m; i++)
{
dp[i] = 1;
}
for (int i = 1; i <= m; i++)
{
for (int j = 1; j < i; j++)
{
//如果曼哈顿距离小于时间差
if (abs(_x[i] - _x[j]) + abs(_y[i] - _y[j]) <= abs(_time[i] - _time[j]))
{
//那么可以抓到这只小鼠,比较dp[i]和通过dp[j]+1得到的哪个方法更好
dp[i] = max(dp[i], dp[j] + 1);
}
}
}
for (int i = 1; i <= m; i++)
{
ans = max(ans, dp[i]);
}
cout << ans << endl;
system("pause");
return 0;
}
查看1道真题和解析