搜狐 2017秋招研发

1:有一条彩色宝石项链,是由很多种不同的宝石组成的,包括红宝石,蓝宝石,钻石,翡翠,珍珠等。有一天国王把项链赏赐给了一个学者,并跟他说,你可以带走这条项链,但是王后很喜欢红宝石,蓝宝石,紫水晶,翡翠和钻石这五种,我要你从项链中截取连续的一小段还给我,这一段中必须包含所有的这五种宝石,剩下的部分你可以带走。如果无法找到则一个也无法带走。请帮助学者找出如何切分项链才能够拿到最多的宝石。

思路:参考别人的,这种题感觉比较烦,找到一个比较好的模板。主要注意点:1,包含一个abcde的串,想要最小,也就是重复的宝石最后出现的位置到现在搜索到的位置的长度,也就是字符最后出现的一个位置,先遍历找到包含五种宝石的最长子串,然后找到前面重复宝石最后出现的位置,两个位置之间就是最小长度。简单的最后出现字符查找的应用啊。2,循环的问题可以把字符串重复两次,就不用取模来判断这些了。可以包含所有情况。

链接:https://www.nowcoder.com/questionTerminal/321bf2986bde4d799735dc9b493e0065
来源:牛客网

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
 
bool judgeColor(int (&index)[5]) {
    for (int i = 0; i < sizeof(index) / sizeof(int); i++) {
        if (!index[i])
            return false;
    }
    return true;
}
int main() {
    using namespace std;
    string str;
    while (getline(cin, str)) {
        int len = str.size();
        str += str;
        int l = 0, r = 0;
        int length = len;
        int index[5] = { 0 };
        for (int i = 0; i < len * 2; i++) {
            if (str[i] - 'A' < 5) {
                index[str[i] - 'A']++;
                if (judgeColor(index)) {
                    while (index[str[l] - 'A'] != 1) {
                        if (str[l] - 'A' < 5) {
                            index[str[l] - 'A']--;
                        }
                        l++;
                    }
                    if (length > r - l + 1) {
                        length = r - l + 1;
                    }
                }
            }
            r++;
        }
        cout << len - length << endl;
    }
    return 0;
}
2, 一只袋鼠要从河这边跳到河对岸,河很宽,但是河中间打了很多桩子,每隔一米就有一个,每个桩子上都有一个弹簧,袋鼠跳到弹簧上就可以跳的更远。每个弹簧力量不同,用一个数字代表它的力量,如果弹簧力量为5,就代表袋鼠下一跳最多能够跳5米,如果为0,就会陷进去无法继续跳跃。河流一共N米宽,袋鼠初始位置就在第一个弹簧上面,要跳到最后一个弹簧之后就算过河了,给定每个弹簧的力量,求袋鼠最少需要多少跳能够到达对岸。如果无法到达输出-1 

思路:过河问题。dp肯定能做,简单的一维dp,先来别人的。

import java.util.Scanner;
 
public class Main {
    static int [] dp=new int [100010];
    static int [] d=new int [100010];
    static int inf=2000000000;
    static int minValue(int n, int m){
        if(n>=m)
        return  m;
        return n;
    }
    public static void main(String[] args) {
        Scanner r=new Scanner(System.in);
        int n=r.nextInt();
         
        for(int i=1; i<=n; i++)
        d[i]=r.nextInt();
         
        for(int i=1; i<=n+1; i++){
            dp[i]=inf;
        }
        dp[1]=0;
        d[n+1]=1;
        for(int i=1; i<=n; i++){
            for(int j=i+1; j<=i+d[i]&&j<=n+1; j++){
                //if(d[j])
                if(d[j]==0)continue;
                dp[j]=minValue(dp[j], dp[i]+1);
            }
        }
        if(dp[n+1]==inf)System.out.println("-1");
        else System.out.println(dp[n+1]);
        r.close();
    }
}

我自己的其实差不多,但是是后面到前面dp的,先找到一步能到岸上的,再找一步能到一次到岸上的,最后看flag[0] 能不能到达,每次记录上一次的最小位置就行,后面的要都是考虑过能最小次数能到到岸上的,要不就是不能到岸上的。
#include <iostream>
#include <vector>
#include <assert.h>
using namespace std;
int main() {
    int n ;
    cin>>n;
    vector<int> re;
    int a = n;
    while(a--) {
        int b ;
        cin>>b;
        re.push_back(b);
    }
    vector<int> flag(n+1,0);
    flag[n] = 1;
    int min1 = n,min2 = n;
    int count = 0, flag2 = 0;
    while(1) {
        min1 = min2;
        for(int i = 0; i < min1; i++) {
            if(flag[i] == 0&&re[i]+i>=min1){
                flag[i] = 1;
                if(i<min2) min2 = i;
                flag2 = 1;
            }
        }
        if(flag2 == 0) {
            cout<<-1;
            return 0;
        }
        count++;
        flag2 = 0;
        if(flag[0] == 1) {
            cout<<count;
            return 0;
        }
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值