• 牛客网 字节跳动2019春招研发部分编程题汇总(7道编程题)


    [编程题] 万万没想到之聪明的编辑

    时间限制:C/C++ 1秒,其他语言2秒

    空间限制:C/C++ 32M,其他语言64M

    我叫王大锤,是一家出版社的编辑。我负责校对投稿来的英文稿件,这份工作非常烦人,因为每天都要去修正无数的拼写错误。但是,优秀的人总能在平凡的工作中发现真理。我发现一个发现拼写错误的捷径:
     
    1. 三个同样的字母连在一起,一定是拼写错误,去掉一个的就好啦:比如 helllo -> hello
    2. 两对一样的字母(AABB型)连在一起,一定是拼写错误,去掉第二对的一个字母就好啦:比如 helloo -> hello
    3. 上面的规则优先“从左到右”匹配,即如果是AABBCC,虽然AABB和BBCC都是错误拼写,应该优先考虑修复AABB,结果为AABCC
     
     
    我特喵是个天才!我在蓝翔学过挖掘机和程序设计,按照这个原理写了一个自动校对器,工作效率从此起飞。用不了多久,我就会出任CEO,当上董事长,迎娶白富美,走上人生巅峰,想想都有点小激动呢!
    ……
    万万没想到,我被开除了,临走时老板对我说: “做人做事要兢兢业业、勤勤恳恳、本本分分,人要是行,干一行行一行。一行行行行行;要是不行,干一行不行一行,一行不行行行不行。” 我现在整个人红红火火恍恍惚惚的……
     
    请听题:请实现大锤的自动校对程序

    输入描述:
    第一行包括一个数字N,表示本次用例包括多少个待校验的字符串。

    后面跟随N行,每行为一个待校验的字符串。

    输出描述:
    N行,每行包括一个被修复后的字符串。

    输入例子1:
    2
    helloo
    wooooooow

    输出例子1:
    hello
    woow


    题解:

    每次取判断是否连续出现3个相同和是否出现"AABB"的形式即可。

    参考代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=1e6+10;
     4 char s[N];
     5 
     6 int main()
     7 {
     8     int n;
     9     cin>>n;
    10     while(n--)
    11     {
    12         cin>>s;
    13         int k=0;
    14         for(int i=0;s[i];i++)
    15         {
    16             s[k++]=s[i];
    17             if(k>=3&&s[k-3]==s[k-2]&&s[k-2]==s[k-1]) k--;
    18             if(k>=4&&s[k-4]==s[k-3]&&s[k-2]==s[k-1]) k--;
    19 
    20         }
    21         s[k]='';
    22         cout<<s<<'
    ';
    23     }
    24     return 0;
    25 }
    C++

    [编程题] 万万没想到之抓捕孔连顺

    时间限制:C/C++ 1秒,其他语言2秒

    空间限制:C/C++ 128M,其他语言256M

    我叫王大锤,是一名特工。我刚刚接到任务:在字节跳动大街进行埋伏,抓捕恐怖分子孔连顺。和我一起行动的还有另外两名特工,我提议
     
    1. 我们在字节跳动大街的N个建筑中选定3个埋伏地点。
    2. 为了相互照应,我们决定相距最远的两名特工间的距离不超过D。
     
    我特喵是个天才! 经过精密的计算,我们从X种可行的埋伏方案中选择了一种。这个方案万无一失,颤抖吧,孔连顺!
    ……
    万万没想到,计划还是失败了,孔连顺化妆成小龙女,混在cosplay的队伍中逃出了字节跳动大街。只怪他的伪装太成功了,就是杨过本人来了也发现不了的!
     
    请听题:给定N(可选作为埋伏点的建筑物数)、D(相距最远的两名特工间的距离的最大值)以及可选建筑的坐标,计算在这次行动中,大锤的小队有多少种埋伏选择。
    注意:
    1. 两个特工不能埋伏在同一地点
    2. 三个特工是等价的:即同样的位置组合(A, B, C) 只算一种埋伏方法,不能因“特工之间互换位置”而重复使用
     

    输入描述:
    第一行包含空格分隔的两个数字 N和D(1 ≤ N ≤ 1000000; 1 ≤ D ≤ 1000000)

    第二行包含N个建筑物的的位置,每个位置用一个整数(取值区间为[0, 1000000])表示,从小到大排列(将字节跳动大街看做一条数轴)

    输出描述:
    一个数字,表示不同埋伏方案的数量。结果可能溢出,请对 99997867 取模

    输入例子1:
    4 3
    1 2 3 4

    输出例子1:
    4

    例子说明1:
    可选方案 (1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)

    输入例子2:
    5 19
    1 10 20 30 50

    输出例子2:
    1

    例子说明2:
    可选方案 (1, 10, 20)

    题解:

    双指针,如果当前r-l>=2,并且a[r]-a[l]<=D,则假设最后一个数就是第三个数,那么ans=ans+len(len-1);

    参考代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 ll C(ll n){return (n-1)*n/2;}
     5  
     6 int main()
     7 {
     8     ll n,d,count=0;
     9     cin>>n>>d;
    10     vector<ll> v(n);
    11     for(int i=0,j=0;i<n;i++) 
    12     {
    13         cin>>v[i];
    14         while(i>=2 && (v[i]-v[j])>d)
    15             j++;
    16         count+=C(i-j);
    17     }
    18     cout<<count%99997867<<endl; 
    19     return 0;
    20 }
    C++

    [编程题]雀魂启动!

    时间限制:C/C++ 1秒,其他语言2秒

    空间限制:C/C++ 32M,其他语言64M

    小包最近迷上了一款叫做雀魂的麻将游戏,但是这个游戏规则太复杂,小包玩了几个月了还是输多赢少。
    于是生气的小包根据游戏简化了一下规则发明了一种新的麻将,只留下一种花色,并且去除了一些特殊和牌方式(例如七对子等),具体的规则如下:
     
    1. 总共有36张牌,每张牌是1~9。每个数字4张牌。
    2. 你手里有其中的14张牌,如果这14张牌满足如下条件,即算作和牌
    • 14张牌中有2张相同数字的牌,称为雀头。
    • 除去上述2张牌,剩下12张牌可以组成4个顺子或刻子。顺子的意思是递增的连续3个数字牌(例如234,567等),刻子的意思是相同数字的3个数字牌(例如111,777)
     
    例如:
    1 1 1 2 2 2 6 6 6 7 7 7 9 9 可以组成1,2,6,7的4个刻子和9的雀头,可以和牌
    1 1 1 1 2 2 3 3 5 6 7 7 8 9 用1做雀头,组123,123,567,789的四个顺子,可以和牌
    1 1 1 2 2 2 3 3 3 5 6 7 7 9 无论用1 2 3 7哪个做雀头,都无法组成和牌的条件。
     
    现在,小包从36张牌中抽取了13张牌,他想知道在剩下的23张牌中,再取一张牌,取到哪几种数字牌可以和牌。
     

    输入描述:
    输入只有一行,包含13个数字,用空格分隔,每个数字在1~9之间,数据保证同种数字最多出现4次。

    输出描述:
    输出同样是一行,包含1个或以上的数字。代表他再取到哪些牌可以和牌。若满足条件的有多种牌,请按从小到大的顺序输出。若没有满足条件的牌,请输出一个数字0

    输入例子1:
    1 1 1 2 2 2 5 5 5 6 6 6 9

    输出例子1:
    9

    例子说明1:
    可以组成1,2,6,7的4个刻子和9的雀头

    输入例子2:
    1 1 1 1 2 2 3 3 5 6 7 8 9

    输出例子2:
    4 7

    例子说明2:
    用1做雀头,组123,123,567或456,789的四个顺子

    输入例子3:
    1 1 1 2 2 2 3 3 3 5 7 7 9

    输出例子3:
    0

    例子说明3:
    来任何牌都无法和牌

    题解:

    这题比较复杂,但是仔细分析,我们枚举这9个数字将其加进去,然后去判断是否可以胡牌即可。

    在判断胡牌的时候,我们枚举每个数量大于1的牌,让其当雀头,数量大于2的牌当刻子或者顺子,递归判断是否成立。

    参考代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 
     5 inline bool ishu(vector<int>num)
     6 {
     7     if(num.empty()) return true;
     8     int count0=0;
     9     for(int i=0;i<num.size();++i)
    10     {
    11         if(num[0]==num[i]) count0++;
    12         else break;
    13     }
    14     //雀头 
    15     if(num.size()%3!=0 && count0>=2)
    16     {
    17         vector<int> newnum(num.begin()+2,num.end());
    18         if(ishu(newnum)) return true;
    19     }
    20     //刻子 
    21     if(count0>=3)
    22     {
    23         vector<int> newnum(num.begin()+3,num.end());
    24         if(ishu(newnum)) return true;
    25     }
    26     //顺子 
    27     if(count(num.begin(),num.end(),num[0]+1)>0 && count(num.begin(),num.end(),num[0]+2)>0)
    28     {
    29         vector<int> newnum(num.begin()+1,num.end());
    30         newnum.erase(find(newnum.begin(),newnum.end(),num[0]+1));
    31         newnum.erase(find(newnum.begin(),newnum.end(),num[0]+2));
    32         if(ishu(newnum)) return true;
    33     }
    34     
    35     return false;
    36 }
    37 
    38 inline bool hupai(vector<int> num,int x)
    39 {
    40     if(count(num.begin(),num.end(),x)==4)
    41         return false;
    42     num.push_back(x);
    43     sort(num.begin(),num.end());
    44     return ishu(num);
    45 }
    46 
    47 int main()
    48 {
    49     vector<int> num,ans;
    50     for(int i=0;i<13;++i)
    51     {
    52         int tmp;
    53         scanf("%d",&tmp);
    54         num.push_back(tmp);
    55     }
    56     
    57     for(int i=1;i<=9;++i)
    58     {
    59         if(hupai(num,i)) 
    60             ans.push_back(i);
    61     }
    62     if(ans.size()==0) puts("0");
    63     else
    64     {
    65         for(int i=0;i<ans.size();++i)
    66             printf("%d%c",ans[i],i==(ans.size()-1)?'
    ':' ');
    67     }
    68     
    69     return 0;
    70 }
    C++

    [编程题] 特征提取

    时间限制:C/C++ 1秒,其他语言2秒

    空间限制:C/C++ 32M,其他语言64M

           小明是一名算法工程师,同时也是一名铲屎官。某天,他突发奇想,想从猫咪的视频里挖掘一些猫咪的运动信息。为了提取运动信息,他需要从视频的每一帧提取“猫咪特征”。一个猫咪特征是一个两维的vector<x, y>。如果x_1=x_2 and y_1=y_2,那么这俩是同一个特征。
           因此,如果喵咪特征连续一致,可以认为喵咪在运动。也就是说,如果特征<a, b>在持续帧里出现,那么它将构成特征运动。比如,特征<a, b>在第2/3/4/7/8帧出现,那么该特征将形成两个特征运动2-3-4 和7-8。
    现在,给定每一帧的特征,特征的数量可能不一样。小明期望能找到最长的特征运动。

    输入描述:
    第一行包含一个正整数N,代表测试用例的个数。

    每个测试用例的第一行包含一个正整数M,代表视频的帧数。

    接下来的M行,每行代表一帧。其中,第一个数字是该帧的特征个数,接下来的数字是在特征的取值;比如样例输入第三行里,2代表该帧有两个猫咪特征,<1,1>和<2,2>
    所有用例的输入特征总数和<100000

    N满足1≤N≤100000,M满足1≤M≤10000,一帧的特征个数满足 ≤ 10000。
    特征取值均为非负整数。

    输出描述:
    对每一个测试用例,输出特征运动的长度作为一行

    输入例子1:
    1
    8
    2 1 1 2 2
    2 1 1 1 4
    2 1 1 2 2
    2 2 2 1 4
    0
    0
    1 1 1
    1 1 1

    输出例子1:
    3

    例子说明1:
    特征<1,1>在连续的帧中连续出现3次,相比其他特征连续出现的次数大,所以输出3

    题解:使用pair和map,记录每个数对的上一个位置所在,和连续存在的长度,取最大值即可。

    参考代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef pair<int,int> pii;
     4 int n,m,k,ans;
     5 
     6 int main()
     7 {
     8     scanf("%d",&n);
     9     while(n--)
    10     {
    11         map<pii,int> preindex,cnt;
    12         scanf("%d",&m); ans=0;
    13         for(int i=1;i<=m;++i)
    14         {
    15             scanf("%d",&k);
    16             for(int j=1;j<=k;++j)
    17             {
    18                 pii pi;
    19                 scanf("%d%d",&pi.first,&pi.second);
    20                 if(preindex[pi]<i-1) cnt[pi]=1;
    21                 else cnt[pi]++;
    22                 preindex[pi]=i;
    23                 ans=max(ans,cnt[pi]);
    24             }
    25         }
    26         printf("%d
    ",ans);
    27     }
    28     
    29     return 0;
    30 }
    C++

    [编程题]毕业旅行问题

    时间限制:C/C++ 1秒,其他语言2秒

    空间限制:C/C++ 32M,其他语言64M

    小明目前在做一份毕业旅行的规划。打算从北京出发,分别去若干个城市,然后再回到北京,每个城市之间均乘坐高铁,且每个城市只去一次。由于经费有限,希望能够通过合理的路线安排尽可能的省一些路上的花销。给定一组城市和每对城市之间的火车票的价钱,找到每个城市只访问一次并返回起点的最小车费花销。

    输入描述:
    城市个数n(1<n≤20,包括北京)

    城市间的车票价钱 n行n列的矩阵 m[n][n]

    输出描述:
    最小车费花销 s

    输入例子1:
    4
    0 2 6 5
    2 0 4 4
    6 4 0 2
    5 4 2 0

    输出例子1:
    13

    例子说明1:
    共 4 个城市,城市 1 和城市 1 的车费为0,城市 1 和城市 2 之间的车费为 2,城市 1 和城市 3 之间的车费为 6,城市 1 和城市 4 之间的车费为 5,依次类推。假设任意两个城市之间均有单程票可购买,且票价在1000元以内,无需考虑极端情况。

    题解:TSP问题。状态压缩DP。

    dp[i][j];表示经过i表示的城市并且以j城市结尾所需的最小费用。然后去判断。

    参考代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3  
     4 int getAns(vector<vector<int>> &nums)
     5 {
     6     const int MAX=0x0fffffff;
     7     int n=nums.size();
     8     int stateNum=1<<n;
     9     // dp[i][j]表示经过了i中的城市,并且以j结尾的路径长度
    10     vector<vector<int> > dp(stateNum,vector<int>(n,MAX));
    11     dp[1][0]=0; 
    12     for(int i=1;i<stateNum;i++)
    13     {
    14         for(int j=0;j<n;j++)
    15         {
    16             if(dp[i][j] != MAX)
    17             { //如果已经访问过
    18                 for(int k=0;k<n;k++)
    19                 {
    20                     if( (i & (1 << k) ) == 0)
    21                         dp[i | (1 << k)][k] = min(dp[i | (1 << k)][k],dp[i][j] + nums[j][k]);
    22                 }
    23             }
    24         }
    25     }
    26     int res = MAX;
    27     for(int i=1;i<n;i++)
    28         res = min(res,dp[stateNum-1][i] + nums[i][0]);
    29     return res;
    30 }
    31 int main()
    32 {
    33    int n;
    34     while(cin>>n)
    35     {
    36         vector<vector<int>> edges(n,vector<int>(n,0));
    37         int x;
    38         for(int i=0; i<n; i++)
    39             for(int j=0; j<n; j++)
    40                 cin>>edges[i][j];
    41             
    42         cout<<getAns(edges)<<endl;
    43     }
    44     return 0;
    45 }
    C++

    [编程题]找零

    时间限制:C/C++ 1秒,其他语言2秒

    空间限制:C/C++ 32M,其他语言64M

    Z国的货币系统包含面值1元、4元、16元、64元共计4种硬币,以及面值1024元的纸币。现在小Y使用1024元的纸币购买了一件价值为的商品,请问最少他会收到多少硬币?

    输入描述:
    一行,包含一个数N。

    输出描述:
    一行,包含一个数,表示最少收到的硬币数。

    输入例子1:
    200

    输出例子1:
    17

    例子说明1:
    花200,需要找零824块,找12个64元硬币,3个16元硬币,2个4元硬币即可。

    题解:

    参考代码:

     1 #include <iostream>
     2 using namespace std;
     3 int main()
     4 {
     5     int num;
     6     while(cin>>num)
     7     {
     8         int cash=1024-num;
     9         int num_64=cash/64;
    10         int num_16=cash%64/16;
    11         int num_4=cash%64%16/4;
    12         int num_1=cash%64%16%4;
    13         cout<<num_64+num_16+num_4+num_1<<endl;
    14     }
    15     return 0;
    16 }
    C++

    [编程题]机器人跳跃问题

    时间限制:C/C++ 1秒,其他语言2秒

    空间限制:C/C++ 32M,其他语言64M

    机器人正在玩一个古老的基于DOS的游戏。游戏中有N+1座建筑——从0到N编号,从左到右排列。编号为0的建筑高度为0个单位,编号为i的建筑的高度为H(i)个单位。 
     
    起初, 机器人在编号为0的建筑处。每一步,它跳到下一个(右边)建筑。假设机器人在第k个建筑,且它现在的能量值是E, 下一步它将跳到第个k+1建筑。它将会得到或者失去正比于与H(k+1)与E之差的能量。如果 H(k+1) > E 那么机器人就失去 H(k+1) - E 的能量值,否则它将得到 E - H(k+1) 的能量值。
     
    游戏目标是到达第个N建筑,在这个过程中,能量值不能为负数个单位。现在的问题是机器人以多少能量值开始游戏,才可以保证成功完成游戏?

    输入描述:
    第一行输入,表示一共有 N 组数据.

    第二个是 N 个空格分隔的整数,H1, H2, H3, ..., Hn 代表建筑物的高度

    输出描述:
    输出一个单独的数表示完成游戏所需的最少单位的初始能量

    输入例子1:
    5
    3 4 3 2 4

    输出例子1:
    4

    输入例子2:
    3
    4 4 4

    输出例子2:
    4

    输入例子3:
    3
    1 6 4

    输出例子3:
    3

    题解:倒着推。由上一个到下一个E变为2E-H,加上下一个的高度之后,变为上一个的两倍。

    参考代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn=1e5+10;
     5 int n,a[maxn],ans=0;
     6 
     7 int main()
     8 {
     9     scanf("%d",&n);
    10     for(int i=1;i<=n;++i)
    11         scanf("%d",a+i);
    12     
    13     for(int i=n;i>0;--i)
    14         ans=(a[i]+ans+1)/2;
    15     
    16     printf("%d
    ",ans);
    17     
    18     return 0;
    19 }
    C++
  • 相关阅读:
    centos8.2安装nginx
    Centos8安装PostgreSQL
    PostgreSQL 安装时提示下载元数据失败
    MySQL8定时备份
    Centos8安装Docker
    Centos8安装中文字体
    Centos8源码安装libgdiplus
    MySQL拖拽排序
    MySQL8修改事务隔离级别
    MySQL启动问题
  • 原文地址:https://www.cnblogs.com/csushl/p/12300119.html
Copyright © 2020-2023  润新知