谷歌面试题-吃糖问题

原文链接
看到上面这个博客中的一道面试题,如下

有一个n*n的棋盘,上面有m个糖果,最开始有一个人在棋盘左上角,他可以向左向右或者向下移动,但不能向上移动,问他最少需要多少步吃完所有糖果。

写一下自己的思路和代码,因为没有OJ可以验证,不知道对错,暂且记录一下。

思路:动态规划求解

动规计算如果从该位置进入下一行(本行及上面所有行的糖果均已拿到),此时走的最少步数。

我们只要是到一行的进入位置和离开位置,根据糖果的位置拿到这一行糖果的步数就是固定的,所以计算dp[i][j]就是从i-1行的每一个位置当做入口,找到最小的步数即为dp[i][j]的值。

糖果的位置 只需要记录每一行最左和最右糖果的位置即可。

注意:

向下走的那一步要记得加上。

动态规划的空间优化,可以使用两行的数组。

可能存在一整行都没有糖果的情况。

#include<iostream>
#include<string>
#include<sstream>
#include<fstream>
#include<algorithm>
#include<iterator>
#include<vector>
using namespace std;

vector<vector<int>> input(){
    string row;
    vector<vector<int>> res;
    while(getline(cin,row)){
        istringstream ss(row);
        istream_iterator<int> eos;
        istream_iterator<int> beg(ss);
        vector<int> tmp;
        copy(beg,eos,back_inserter(tmp));
        res.push_back(move(tmp));
    }
    return res;
}

int min_steps(const vector<vector<int>>& data){
    if(data.empty())
        return -1;
    int row = data.size();
    int col = data[0].size();
    int est[100000][2];
    for(int i=0;i<row;i++)
    {
        est[i][0]=col;
        est[i][1]=-1;
    }
    //est[0][0]=0;
    //est[0][1]=0;

    for(int i=0;i<row;i++)
    {
        for(int j=0;j<col;j++)
        {
            if(data[i][j]) continue;
            if(j<est[i][0]) est[i][0]=j;
            if(j>est[i][1]) est[i][1]=j;
        }
    }
    for(int i=0;i<row;i++)
    {
        cout<<est[i][0]<<" "<<est[i][1]<<"est"<<endl;
    }
    if(row==1) 
    {
        return est[0][1];
    }
    int m[2][2];
    m[0][0]=2*est[0][1]-est[0][0];
    m[0][1]=est[0][1];
    cout<<m[0][0]<<" "<<m[0][1]<<"m[0]"<<endl;
    int step=0;
    int a=m[0][0],b=m[0][1];
    for(int i=1;i<row;i++)
    {
        step=1-step;
        if(est[i][1]<est[i][0])
        {
            m[step][0]=m[1-step][0]+1;
            m[step][1]=m[1-step][1]+1;
            est[i][0]=est[i-1][0];
            est[i][1]=est[i-1][1];
            cout<<m[step][0]<<" "<<m[step][1]<<"m[step]continue"<<endl;
            continue;
        }
        m[step][0] = est[i][1]-est[i][0]+min(m[1-step][0]+abs(est[i][1]-est[i-1][0]),m[1-step][1]+abs(est[i][1]-est[i-1][1]))+1;
        m[step][1] = est[i][1]-est[i][0]+min(m[1-step][0]+abs(est[i][0]-est[i-1][0]),m[1-step][1]+abs(est[i][0]-est[i-1][1]))+1;
        cout<<est[i][0]<<" "<<est[i][1]<<" "<<est[i-1][0]<<" "<<est[i-1][1]<<"estfor"<<endl;
        cout<<m[step][0]<<" "<<m[step][1]<<"m[step]"<<endl;
        a=m[step][0];
        b=m[step][1];
    }
    return min(a,b);
}
int main(){
    cout << min_steps(input()) << endl;
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值