字节跳动2019届校招笔试题

1.世界杯开幕式会在球场C举行,球场C的球迷看台可以容纳M*N个球迷。在球场售票完成后,现官方想统计此次开幕式一共有多少个球队球迷群体,最大的球队球迷群体有多少人。

经调研发现,球迷群体在选座时有以下特性:

同球队的球迷群体会选择相邻座位,不同球队的球迷群体会选择不相邻的座位(注解:相邻包括前后相邻,左右相邻,斜对角相邻)

给定一个M*N的二维球场,0代表该位置没有坐人,1代表该位置已有选择,希望输出球队群体个数P,最大的球队群体人数Q

输入描述:

第一行,2个数字,M及N,使用英文逗号分隔

接下来M行,每行N的数字,使用英文逗号分隔

输出描述:

一行,2个数字,P及Q,使用英文逗号分隔

其中P表示球队群体个数,Q表示最大的球队群体人数

例:输入

10,10

0,0,0,0,0,0,0,0,0,0

0,0,0,1,1,0,1,0,0,0

0,1,0,0,0,0,0,1,0,1

1,0,0,0,0,0,0,0,1,1

0,0,0,1,1,1,0,0,0,1

0,0,0,0,0,0,1,0,1,1

0,1,1,0,0,0,0,0,0,0

0,0,0,1,0,1,0,0,0,0

0,0,1,0,0,1,0,0,0,0

0,1,0,0,0,0,0,0,0,0

输出:6,8

代码如下:


#include<iostream>
#include<vector>
#include<string>

using namespace std;

int getNum(vector<vector<int>>& people,int i,int j,vector<vector<int>>& reach)
{
    int m=people.size(),n=people[0].size();
    if(i>=m||j>=n||i<0||j<0){
        return  0;
    }
    else if(people[i][j]==1&&reach[i][j]==0){
        reach[i][j]=1;
        int n1=getNum(people,i-1,j,reach)+getNum(people,i+1,j,reach);
       int n2=getNum(people,i,j-1,reach)+getNum(people,i,j+1,reach);
       int n3=getNum(people,i-1,j-1,reach)+getNum(people,i-1,j+1,reach);
       int n4=getNum(people,i+1,j-1,reach)+getNum(people,i+1,j+1,reach);
        return n1+n2+n3+n4+1;
    }else {
		return 0;}
    }
void getdata(vector<vector<int>>& people,vector<int>& num,vector<vector<int>>& reach)
{
    int m=people.size(),n=people[0].size();
    for(int i=0;i<m;i++)
        for(int j=0;j<n;j++) {
            if(people[i][j]==1&&reach[i][j]==0){
                int n=getNum(people,i,j,reach);
                num.push_back(n);
            }
        }
}
int main()
{
    int m;
    int n;
    char c;
    cin>>m>>c>>n;
    vector<vector<int> > people;
    vector<int> vtemp(n,0);
    vector<vector<int>> reach(m,vtemp);
    for(int i=0;i<m;i++){
		vector<int> ptemp;
		int temp;
		char cc;
		for(int j=0;j<n-1;j++){
			cin>>temp;
			cin>>cc;
			ptemp.push_back(temp);
		}
		cin>>temp;
		ptemp.push_back(temp);
	    people.push_back(ptemp);
	}
    vector<int>num;
    if(people.empty()){
        cout<<0<<','<<0<<endl;
        return 0;
    }
    getdata(people,num,reach);
    vector<int>::iterator max=max_element(nums.begin(),nums.end());
    cout<<num.size()<<","<<*max<<endl;
    return 0;
}

2.为了提高文章质量,每一篇文章(假设全部都是英文)都会有m民编辑进行审核,每个编辑独立工作,会把觉得有问题的句子通过下表记录下来,比如[1,10],1表示病句的第一个字符,10表示病句的最后一个字符。也就是从1到10着10个字符组成的句子,是有问题的。

现在需要把多名编辑有问题的句子合并起来,送个总编辑进行最终的审核。比如编辑A指出的病句是[1,10],[32,45];编辑B指出的病句是[5,16],[78,94]那么[1,10]和[5,16]是有交叉的,可以合并成[1,16][32,45][78,94]

输入描述:

编辑数量m,之后每行是每个编辑的标记的下表组合,第一个和最后一个下标用英文逗号分隔,每组下标之间用分号分隔

输出描述:

合并后的下标集合,第一个和最后一个下标用英文逗号分隔,每组下标之间用分号分隔。返回结果是从小到大递增排列

例:输入

3

1,10;32,45

78,94;5,16

80,100;200,220;16,32

输出: 1,45;78,100;200,220

代码如下:

#include<iostream>
#include<vector>
#include<utility>
#include<algorithm>
 
using namespace std;
 
void mergeIndex(vector<pair<int,int>>& vp)
{
   sort(vp.begin(),vp.end(),[](pair<int,int>& temp1,pair<int,int>& temp2){return temp1.first<temp2.first;});
   int n=vp.size();
   for(auto it=vp.begin();it<vp.end()-1;)
   {
       if(it->second>=(it+1)->first-1)
         {
               if((it+1)->second>it->second){
                  it->second=(it+1)->second;
                }
               it=vp.erase(it+1);
               --it;
         }else{
             ++it;
         }
   }
}
int main()
{
   vector<pair<int,int>> vp;
  int m;
  cin>>m;
  int first,last;
  char c1,c2;
  for(int i=0;i<m;i++)
   {
      do
      {
        cin>>first;
        if(cin.get()==',')
          {
              cin>>last;
              vp.push_back(make_pair(first,last));
          }
       }while(cin.get()==';');
   }
   mergeIndex(vp);
   int i=0;
  for(;i<vp.size()-1;i++)
    {
        cout<<vp[i].first<<","<<vp[i].second<<";";
    }
  cout<<vp[i].first<<","<<vp[i].second<<endl;
  cout<<endl;
   return 0;
}

3. 小a和小b玩一个游戏,有n张卡牌,每张上面有两个正整数x,y。取一张牌时,个人积分增加x,团队积分增加y。求小a,小b各取若干张牌,使得他们的个人积分相等,且团队积分最大。

输入描述:

第一行n

接下来n行,每行两个正整数x,y

输出描述:

一行一个整数

表示小a的积分和小b的积分相等时,团队积分的最大值

例:输入

4

3 1

2 2

1 4

1 4

输出:10

说明:当a抽取(2,2),b抽取(1,4),(1,4)时,两人个人积分都是2,团队积分最大,为10分

代码如下:

#include<iostream>
#include<vector>
#include<utility>
#include<algorithm>
using namespace std;

int main()
{
	int n;
	cin >> n;
	vector<pair<int, int>> vp;
	int a, b,cap=0;
	for(int i=0;i<n;i++){
		cin >> a >> b;
		vp.push_back(make_pair(a, b));
		cap = cap < a ? a : cap; 
	}
	sort(vp.begin(), vp.end(), [](pair<int, int>& p1, pair<int, int>& p2) {return p1.second > p2.second; });
	int** dp = new int* [n];
	for (int i = 0; i<n; i++){
		dp[i] = new int[cap+1];
	}
	for (int j = 0; j <=cap; j++) {
		dp[n-1][j] = 0;
	}
	for (int i = n-2; i>=0; i--){
		for (int j = 0; j <= cap; j++){
			int point1 = (j >=vp[i].first) ? dp[i + 1][j- vp[i].first] + vp[i].second : 0;   //x[i]和cap-x[i]不能确定谁大
			int point2 = (j<=cap- vp[i].first) ? dp[i + 1][j+ vp[i].first] + vp[i].second : 0;//这样省去了划分区间的麻烦
			dp[i][j] = max({ dp[i + 1][j], point1, point2 });
		}
	}      
	cout << dp[0][0] << endl;
	for (int i = 0; i < n; i++) {
		delete [] dp[i];
	}
	delete [] dp;
	return 0;
}

4. 两个长度为n的序列a,b。问有多少个区间[l,r]满足max(a[l,r])<min(b[l,r])即a区间的最大值小于b区间的最小值数据范围:n<1e5,a(i),b(i)<1e9

输入描述:

第一行一个整数n

第二行n个数,第i个为a(i)

第三行n个数,第i个为b(i)

0<1<=r<n

输出描述:

一行一个整数,表示答案

例1:输入

3

3 2 1

3 3 3

输出: 3

 

5. 小明在抖音里关注了N个主播,每个主播每天的开播时间是固定的,分别在S时刻开始开播,t时间结束。小明无法同时观看两个主播的直播。一天被分成了M个时间单位。请问小明每天最多能完整观看多少场直播?

输入描述:

第一行一个整数,代表N

第二行一个整数,代表M

第三行空格间隔的N*2个整数,代表s,t

输出描述:

一行一个整数,表示答案

例1:输入

3

10

0 3 3 7 7 0

输出:3

例2: 输入

3

10

0 5 2 7 6 9

输出:2

备注:数据范围1<=N<=10^5

2<=M<=10^6

0<=s(i),t(i)<M (s(i)!=t(i))

s(i)>t(i)代表时间跨天,但直播时长不会超过一天

.

 

本题和寻找图中路径的思想一致。代码如下:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

bool rfind(int s, int des, int n, int& length, int* reach, int* path, vector<vector<int>>& red)
{
	reach[s] = 1;
	for (int u = 1; u <= n; u++){
		if (red[s][u] != 0 && reach[u] == 0) {
			path[++length] = u;
			if (u == des || rfind(u, des, n, length, reach, path, red)) {
				return true;
			}
			length--;
		}
	}
	return false;
}
int* findPath(int begin, int end, int n, vector<vector<int>>& red)
{
	int* path = new int[n + 1];
	path[1] = begin;
	int length = 1;
	int des = end;
	int* reach = new int[n + 1];
	for (int i = 1; i <= n; i++) {
		reach[i] = 0;
	}
	if (begin == end || rfind(begin, des, n, length, reach, path, red)) {
		path[0] = length - 1;
	}
	else {
		delete[] path;
		path = NULL;
	}
	delete[] reach;
	return path;
}
int main()
{
	int n, m;
	cin >> n;
	cin >> m;
	vector<int> vtemp(n + 1, 0);
	vector<vector<int>> red(n + 1, vtemp);
	int row, col;
	for (int i = 0; i<m; i++){
		cin >> row >> col;
		red[row][col] = 1;
	}
	bool isred = true;
	int t = 0;
	for (int i = 1; i <= n; i++){
		isred = true;
		for (int j = 1; j <= n; j++){
			int* path = findPath(j, i, n, red);
			if (path == NULL){
				isred = false;
				break;
			}
			else {
				delete[] path;
			}
		}
		if (isred) {
			++t;
		}
	}
	cout << t << endl;
	return 0;
}

 

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值