百度2015春季实习生招聘附加题

题目链接:http://www.nowcoder.com/test/question/analytic?tid=1470549
[编程题] 今天要吃点好的!
加班了一个通宵的度度熊,神经有点恍惚,想到依然未能解决的Bug,眼泪禁不住霹雳哗啦往下掉……他抬头看了看帝都灰蒙蒙的天空,一咬牙,一跺脚,大叫一声——劳资今天要吃点好的! 已知本厂有n个食堂,第i(i属于[1,n])个食堂有m[i]种食物,每种食物有一个价钱c,享受度v,度度熊希望去一个食堂就餐,花费[bot,top]范围内的钱数(也可以拍桌子走人,哪里都不吃了),选择若干种食物,使得自己所能获得的享受度最大。(注意,度度熊还有一个挑食的特点,同一种食物他最多只会点一份。) 现在告诉你所有食堂食物的信息,希望你进行选择搭配,使得度度熊可以得到最大的享受度,并输出这个享受度的值。 
输入描述:
第一行是一个正整数T(1<=T<=20),表示有T组测试数据。
对于每组数据——
第一行是三个数n,bot,top,n代表食堂数1<=n<=10),bot是这次吃饭的最低消费,top是这次吃饭的最高消费(0<=bot,top<=10000)
接下来依次是n个食堂的信息,对于第i个食堂
第一行是一个数m[i](o<=m[i]<=100),代表第i个食堂的食物数
第二行有2*m[i]个数,分别是c[i][1],v[i][1],c[i][2],v[i][2],……c[i][m[i]],v[i][m[i]]
c[i][j]表示第i个餐厅第j种食物的价钱,v[i][j]代表第i个餐厅第j种食物给度度熊带来的享受度。


输出描述:
对于每组数据,请输出一行,每行一个正整数。表示度度熊所能获得的最大享受度。
数据结果保证不会超过2^31-1.

输入例子:
2
2 10 20
5 1 1 2 1 5 1 10 1 20 1
5 1 2 2 2 5 2 10 2 20 2
2 10 10
1 5 1
1 5 1

输出例子:
8
0
01背包应用!

对每个食堂,做01背包,然后取最大的。

这里是区间[bot,top],所以我们可以通过背恰好重量的东西来解决!


#include<stdio.h>
#include<algorithm>
#include<string.h>
#define LL __int64
using namespace std;

int main()
{
    int T,n,bot,top;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&bot,&top);

        int m;
        int c[105],v[105];
        int ans=0,tmp;
        for(int i=0;i<n;i++)
        {
            int f[10005];
            //初始化
            memset(f,-1,sizeof(f));
            f[0]=0;

            scanf("%d",&m);
            for(int j=0;j<m;j++)
            {
                scanf("%d%d",&c[j],&v[j]);
            }

            for(int k=0;k<m;k++)
            {
                for(int vv=top;vv>=c[k];vv--)
                {
                    if(f[vv]<f[vv-c[k]]+v[k]&&f[vv-c[k]]>=0)//满足恰好背的情况
                    {
                        f[vv]=f[vv-c[k]]+v[k];
                    }
                }
            }
            for(int k=bot;k<=top;k++)
            {
                ans=max(ans,f[k]);
            }

        }
        printf("%d\n",ans);
    }
    return 0;
}

我在做的时候,是记录背包的实际重量来想的。

#include<stdio.h>
#include<algorithm>
#define LL __int64
using namespace std;

int main()
{
    int T,n,bot,top;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&bot,&top);
        int m;
        int c[105],v[105];
        int ans=0,tmp;
        for(int i=0;i<n;i++)
        {
            int f[10005]={0},w[10005]={0};
            scanf("%d",&m);
            for(int j=0;j<m;j++)
            {
                scanf("%d%d",&c[j],&v[j]);
            }
            for(int k=0;k<m;k++)
            {
                for(int vv=top;vv>=c[k];vv--)
                {
 
                    if(f[vv]<f[vv-c[k]]+v[k])
                    {
                        f[vv]=f[vv-c[k]]+v[k];
                        w[vv]=w[vv-c[k]]+c[k];
                    }
 
                }
            }
            for(int k=bot;k<=top;k++)
            {
                if(w[k]>=bot&&w[k]<=top) ans=max(ans,f[k]);
            }
 
        }
        printf("%d\n",ans);
    }
    return 0;
}

第二题:


[编程题]01排序
给定一个01串(仅由‘ 0’或‘1’组成的字符串),现在想把这个数字串排序成“非递减”有序序列,请问至少需要多少次交换(任意两个位置交换)? 
输入描述:
输入数据第一行是一个正整数T(T<=100),表示有T组测试数据;
接下来的T行,每行给出01串。
数据保证——
50%的字符串长度在[1,100 ]
95%的字符串长度在[1,10000]
100%的字符串长度在[1,1000000]


输出描述:
对于每组测试数据,请输出排成“非递减有序序列”的最小交换次数。
每组输出占一行。

输入例子:
3
01
10
110

输出例子:
0
1
1
这题思路很简单,就是统计长度为n里有cnt个0,并记录0的位置,从最后一个0开始往前找,如果大于等于cnt,ans++表明,这个0,需要移动!特判全0和全1的情况!


#include<stdio.h>
#include<string.h>

char ch[1000005];
int div[1000005];
int main()
{

    int T;
    scanf("%d",&T);
    getchar();
    while(T--)
    {

        gets(ch);
        //puts(ch);
        int cnt=0;
        int len=strlen(ch);
        for(int i=0;i<len;i++)
        {
            if(ch[i]=='0') div[cnt++]=i;
        }
 //       printf("%d\n",cnt);
        if(!cnt||cnt==len) {printf("0\n");continue;}

        int ans=0;
        for(int i=cnt-1;i>=0;i--)
        {
            if(div[i]<cnt) break;
            if(div[i]>=cnt) ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}


你可能感兴趣的:(百度2015春季实习生招聘附加题)