搜狐 2017秋招研发

来源:互联网 发布:淘宝店铺关注排行 编辑:程序博客网 时间:2024/04/30 04:00

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;}



原创粉丝点击