hello,大家好,这里是bang___bang_,本篇记录2道牛客习题,年终奖(简单),迷宫问题(中等),如有需要,希望能有所帮助!
目录
1️⃣年终奖
2️⃣迷宫问题
1️⃣年终奖
年终奖_牛客题霸_牛客网 (nowcoder.com)
描述
小东所在公司要发年终奖,而小东恰好获得了最高福利,他要在公司年会上参与一个抽奖游戏,游戏在一个6*6的棋盘上进行,上面放着36个价值不等的礼物,每个小的棋盘上面放置着一个礼物,他需要从左上角开始游戏,每次只能向下或者向右移动一步,到达右下角停止,一路上的格子里的礼物小东都能拿到,请设计一个算法使小东拿到价值最高的礼物。
给定一个6*6的矩阵board,其中每个元素为对应格子的礼物价值,左上角为[0,0],请返回能获得的最大价值,保证每个礼物价值大于100小于1000。
解题思路:
这道题问题是使小东拿到价值最高的礼物,也就是说每次都需要上一步中拿到最高价值的礼物,从而推导到最后的大规模拿到最高(最优)价值的礼物——动态规划。
小东每次只能向下或者向右移动一步,也就是说当前问题解的来源只能是向上和向左中来。
递推公式:dp[ i ] [ j ]=max(dp[ i-1] [ j ] , dp[ i ] [ j -1 ] )+ board[ i ] [ j ]
另外我们还应当注意到边界情况:
- 当i=0时,每次的最大价值只能从左边中来:dp[ i ] [ j ]=dp[ i ] [ j-1 ]+board[ i ] [ j ]
- 当j=0时,每次的最大价值只能从上边中来:dp[ i ] [ j ]=dp[ i-1 ] [ j ]+board[ i ] [ j ]
代码实现:
class Bonus {
public:
int getMost(vector<vector<int> > board) {
int ROW=board.size();//获取行
int COL=board[0].size();//获取列
vector<vector<int>>allPrice(ROW,vector<int>(COL,0));//记录已获得的礼物价值
allPrice[0][0]=board[0][0];
for(int i=0;i<ROW;i++)
{
for(int j=0;j<COL;j++)
{
if(i==0&&j==0)
continue;
if(i==0)
{
allPrice[i][j]=allPrice[i][j-1]+board[i][j];
//获取i=0的礼物价值,只能是左边已获得价值加当前价值
}
else if(j==0)
{
allPrice[i][j]=allPrice[i-1][j]+board[i][j];
//获取j=0的礼物价值,只能是上边已获得价值加当前价值
}
else {
allPrice[i][j]=board[i][j]+max(allPrice[i-1][j],allPrice[i][j-1]);
//其他位置的最大价值,为左边或者上面最大价值+当前价值
}
}
}
return allPrice[ROW-1][COL-1];
}
};
2️⃣迷宫问题
迷宫问题_牛客题霸_牛客网 (nowcoder.com)
描述
定义一个二维数组 N*M ,如 5 × 5 数组下所示:
int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的路线。入口点为[0,0],既第一格是可以走的路。
注意:不能斜着走!
数据范围: 2≤n,m≤10 , 输入的内容只包含: 0≤val≤1
输入描述:
输入两个整数,分别表示二维数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。
输出描述:
左上角到右下角的最短路径,格式如样例所示。
示例1:
输入:
5 5 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0输出:
(0,0) (1,0) (2,0) (2,1) (2,2) (2,3) (2,4) (3,4) (4,4)
示例2:
输入:
5 5 0 1 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 1 1 0 0 0 0 0 0输出:
(0,0) (1,0) (2,0) (3,0) (4,0) (4,1) (4,2) (4,3) (4,4)
解题思路:
1.从入口开始进行dfs搜索,每到一个点,入临时路径数组(path)并将当前位置建“墙”,表示已达。
2.判断是否到达终点,若到达终点,判断当前结果数组(res)是否为空||结果数组(res)大小>临时路径数组(path)大小(为了找到最短路径),进行结果数组的替换。
3.若未到终点,从4个方向进行遍历搜索,若无"墙"(0),即可以达到。
4.若4个方向都不可达,即进入死路,开始回溯!!
代码实现:
#include <iostream>
#include <vector>
using namespace std;
vector<pair<int,int>>res;
vector<pair<int,int>>path;
vector<vector<int>>map;
int ROW,COL;
void dfs(int x,int y)
{
map[x][y]=1;//走过,建墙
path.push_back(make_pair(x,y));
//走到终点
if(x==ROW-1&&y==COL-1)
{
//返回res
if(res.empty()||res.size()>path.size())
{
res=path;
}
}
//未走到终点,开始遍历走迷宫
//向右走
if(y+1<COL&&map[x][y+1]==0)
dfs(x,y+1);
//向下走
if(x+1<ROW&&map[x+1][y]==0)
dfs(x+1,y);
//向左走
if(y-1>=0&&map[x][y-1]==0)
dfs(x,y-1);
//向上走
if(x-1>=0&&map[x-1][y]==0)
dfs(x-1,y);
//走到死路,恢复标记墙,开始回溯
map[x][y]=0;
path.pop_back();//退出路径
}
int main()
{
while(cin>>ROW>>COL)
{
map=vector<vector<int>>(ROW,vector<int>(COL,0));
res.clear();//清空上次的数据
path.clear();//清空上次的数据
for(int i=0;i<ROW;i++)
{
for(int j=0;j<COL;j++)
{
cin>>map[i][j];
}
}
dfs(0,0);
for(auto& e:res)
{
cout<<"("<<e.first<<","<<e.second<<")"<<endl;
}
}
return 0;
}
文末结语,本篇记录了2道牛客习题,1道动态规划的简单题(年终奖);1道DFS+回溯的中等题(迷宫问题),本文旨在记录,如有需要,希望能有所帮助!!