字节跳动2019暑期实习生算法岗笔试题


       笔试共有4道编程题,每道题20分,两个小时。这个题感觉比腾讯的简单一点。以下内容的编写全凭记忆和个人理解,如有什么不对的地方,希望大家见谅。

第一题

题意

       有一个人用一张1024元的纸币购买价值n元的商品,卖家用四种硬币找零,分别是1、4、16、64,问卖家找零最少需要多少个硬币。

思路

       将硬币面值从小到大排序,计算即可。

代码

#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<string>

using namespace std;

int main()
{
    int n ;
    while(scanf("%d",&n)!=EOF)
    {
        int rec = 1024 - n;
        int num64 = rec / 64;
        rec = rec - 64*num64;
        int num16 = rec / 16;
        rec = rec - 16*num16;
        int num4 = rec / 4;
        rec = rec - 4*num4;
        int num1 = rec / 1;
        rec = rec - 1*num1;
        printf("%d\n",num64+num16+num4+num1);
    }
    return 0;
}

第二题

题意

       有一个程序员写了个自动处理字符串的代码,规则有两条:①如果有aabb型子串,改为aab;②如果有ccc型子串,改为cc。让我们复现程序员的代码。

思路

       模拟题,我的思路是将字符串中不符合规则的位置用字符’@'代替,最后输出的时候忽略这些位置即可。

代码

#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<string>

using namespace std;

char s[8000000];

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",s);
        int len = strlen(s);
        for(int i = 0 ; i < len; )
        {
            int next1 = i+1;
            while(s[next1] == '@' && next1<len)
                ++next1;
            int next2 = next1+1;
            while(s[next2] == '@' && next2<len)
                ++next2;
            int next3 = next2+1;
            while(s[next3] == '@' && next3<len)
                ++next3;
            if(s[i]==s[next1] && s[next1]==s[next2])
            {
                s[i] = '@';
                i = i+1;
                continue;
            }
            else if(s[i]==s[next1] && s[next2]==s[next3])
            {
                s[next2] = '@';
                continue;
            }
            else
            {
                i = i+1;
                continue;
            }
        }
        for(int i=0;i<len;++i)
            if(s[i]!='@')
                printf("%c",s[i]);
        printf("\n");
    }
    return 0;
}

第三题

题意

       老师要给一群学生根据他们的成绩发奖品,学生们围在一个圆桌周围,每个人都有自己的成绩。发奖品的规则是:①每个学生都至少有一个奖品;②如果某学生比左右邻座的学生成绩好,那他应收到比他们更多的奖品。问:老师至少需要准备多少个奖品。

思路

       按照成绩从小到大排序,依次发奖品即可。这里用到了结构体排序。

代码

#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<string>

using namespace std;

int num[100000+10];

struct TMP
{
    int num,ll,rr,rec;
    int pos;
}tmp[100000+10],org[100000+10];

int cmp(TMP a, TMP b)
{
    return a.num < b.num;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;++i)
        {
            scanf("%d",&tmp[i].num);
            if(i == 0)
            {
                tmp[i].ll=n-1;
                tmp[i].rr=1;
            }
            else if(i == n-1)
            {
                tmp[i].ll=n-2;
                tmp[i].rr=0;
            }
            else
            {
                tmp[i].ll=i-1;
                tmp[i].rr=i+1;
            }
            tmp[i].rec=1;
            tmp[i].pos=i;

            org[i].rec = tmp[i].rec;
            org[i].ll = tmp[i].ll;
            org[i].rr = tmp[i].rr;
            org[i].num = tmp[i].num;
        }
        sort(tmp, tmp+n, cmp);
//        for(int i=0; i<n; ++i)
//            printf("%d %d %d %d %d\n",tmp[i].pos, tmp[i].num, tmp[i].ll, tmp[i].rr, tmp[i].rec);

        for(int i=0; i<n; ++i)
        {
            int pos = tmp[i].pos;
            int should_rec = org[pos].rec;
            if(org[pos].num > org[org[pos].ll].num)
                should_rec = max(should_rec, org[org[pos].ll].rec+1);
            if(org[pos].num > org[org[pos].rr].num)
                should_rec = max(should_rec, org[org[pos].rr].rec+1);
            org[pos].rec = should_rec;
            //printf("%d %d %d %d %d\n",org_pos, tmp[i].num, tmp[i].ll, tmp[i].rr, tmp[i].rec);
        }

        int ans = 0;
        for(int i=0; i<n; ++i)
        {
            //printf("%d ",org[i].rec);
            ans += org[i].rec;
        }
        printf("%d\n",ans);
    }
    return 0;
}

第四题

题意

       有n根绳子,给出每根的长度。现在要求从这n根绳子中剪出m根等长的绳子(注:不能拼接),问等长绳子最长多长。

思路

       等长绳子最短为0,最长肯定不超过n根绳子中最长的绳子长度,所以将左端点设置为0,右短点设置为最长绳长,二分+判断,就可以了。需要注意二分的终止条件那里,精度不能设置的太高,否则会WA,设置成题意中的0.01即可,或者0.001。

代码

#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<string>

using namespace std;

int num[100000+10];
int n,m;

int _check(double _need)
{
    int ans = 0;
    for(int i=n;i>=1;--i)
    {
        double tmp = num[i]*1.0;
        ans = ans + (tmp/_need);
    }
    if(ans >= m)
        return 1;
    else
        return 0;
}

int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=1;i<=n;++i)
            scanf("%d",&num[i]);
        sort(num+1,num+1+n);
        double ll = 0;
        double rr = num[n];
        while((rr-ll) > 0.001)
        {
            double mm = (ll+rr)/2;
            if(_check(mm))
                ll = mm;
            else
                rr = mm;
        }
        printf("%.2f\n", ll);
    }
    return 0;
}
  • 9
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值