【字节跳动2019年】算法岗笔试题

题目描述:

字节跳动大街上有许多商铺,其中只有一部分为顾客开放厕所。街道办想提供一项便民服务, 在家商铺门口放一个标志,写明距离当前商铺最近的厕所有几个商铺的距离。如果当前商铺就有厕所,则标志为0。请帮助街道办的同志完成这项工作。
PS:已知整条街上至少有一个厕所。

输入描述:

第一行包含个正整数N (1 <= N <= 1000000),代表街上总共的商铺数量

第二行包含一个字符串, 由N个字符组成,每个字符要么为"O", 代表有厕所;要么为"X",代表无厕所

输出描述:

输出一行,包含N个非负数字,每个数字代表最近的厕所与当前商铺之间的距离

输入:

9

XXOXOOXXX

输出

2 1 0 1 0 0 1 2 3

题解:简单的题目,用到一个二分去查找即可,

代码:

#include <bits/stdc++.h>           

#define LL long long
#define LLFmt "%lld"
const int MINT = -1000000000;
const int MAXT = 1000000000;

using namespace std;

int findLastSmaller(int array[], int key, int len) {
    int left = 0;
    int right = len - 1;

    while (left <= right) {
        int mid = (left + right) / 2;
        if (array[mid] >= key) {
            right = mid - 1;
        }
        else {
            left = mid + 1;
        }
    }
    return right;
}

int findFirstLarger(int array[], int key, int len) {
    int left = 0;
    int right = len - 1;

    while (left <= right) {
        int mid = (left + right) / 2;
        if (array[mid] >= key) {
            right = mid - 1;
        }
        else {
            left = mid + 1;
        }
    }
    return left;
}

int main () {
//	freopen("input.txt", "r", stdin);
	int n, index[100000 + 7] = { 0 }, len = 0;
	cin >> n; 
	
	char str[1000000 + 7];
	cin >> str; 
	
	index[len++] = MINT;
	for (int i = 0; i < n; i++) {
		if (str[i] == 'O') index[len++] = i + 1;
	}
	index[len++] = MAXT;
	
	
	for (int i = 0; i < n; i++) {
		int lo = findLastSmaller(index, i + 1, len);
		int hi = findFirstLarger(index, i + 1, len);
		
		cout << (i == 0 ? "" : " ") << min( i + 1 - index[lo], index[hi] - (i + 1));
	}
	
	cout << endl;
	return 0;
}

/*
9
XXOXOOXXX
*/

题目描述:

小明马上要参加期末考试,所以他特意用一段时间来做练习题,这段时间为m秒。一共有序号1~n的n道题目。小明从序号1的题目开始做。按照序号递增的顺序开始解答。每道题如果解答需要消耗时间a[i](如果剩余的时间不足a[i]则无法解答),如果跳过则不消耗时间。
因为每道题都可能帮助到期末考试,小明想知道对于每一道题最少需要放弃前面几道题,才能解答完成。

输入描述:

第一行是样例个数;
每个样例的第一行是n, m,表示n道题目和练习时长m秒; (1<= n<= 1,000, 1<=m<=1,000,000
第二行是n个数字a[i],分别表示n道题的解答耗时为a[i]秒,(题目保证所有的a[i] <= m)

输出描述:
每个样例输出一行,一行包括n个数字, 分别n个题目如果完成需要放弃前面的最少题目数;

输入:

2

5 5

1 2 3 4 5

4 4

4 3 2 1

输出:

0 0 1 2 4

0 1 2 2

题解:暴力即可

代码:

#include <bits/stdc++.h>           
using namespace std;

int s[1009], ss[1009];
int main()
{
    int T, n, m;
    cin >> T;
    while(T--){
        cin >> n >> m;
        for(int i = 0; i < n; i++)
            cin >> s[i];
        cout << "0";
        int M;
        M = m;
        for(int i = 1; i < n; i++){
            M = M - s[i];
            int k = 0;
            for(int j = 0; j < i; j++){
                ss[k++] = s[j];
            }
            sort(ss, ss + k);
            int x, d = 0;
            for(x = 0; x < k; x++){
                if(ss[x] <= M){
                    M -= ss[x];
                    d++;
                }
                else
                    break;
            }
            cout << " " << i - d;
            M = m;
        }
        cout << endl;
    }
    return 0;
}

题目描述:

小明在一个家官像主义非常严重的公司工作,有天领导安排他去找领导1签一个合同。
小明找到1,1说: 我需要2,3, 4三位领导签字。
小明找到2,2说:我需要5领导签字。
小明找到5,5说:我需要3领导签字.
小明找到4,4说:我需要3领导签字。
小明最后找到3,3说:我可以给你签字,但是今天很晚了,明天来吧。
第二天小明起了个大早,依次去找3->4->5->2->1. 最后终于一天之内把合同给签了。
请你帮助小明找到正确的找领导签字的顺序。
(注:在字节跳动不会发生这种情况)

输入描述:

每一行输入都是用空格隔开的整数,每一行的第一个数字代表的是某领导,后面的数字代表该领导依赖的别的领导的签字。

输出描述:

是一行数字,用空格隔开,从左往右是应该找领导的顺序。如果当你能同时找多位领导签字的时候,优先找数字最小的那位。
当你无法完成这项任务的时候,输出-1

输入:

1

2 1

3 2

4 1

5 1 3 4

输出:

1 2 3 4 5

题解:一个图的拓扑应用

代码:

#include <bits/stdc++.h>           
using namespace std;

#define LL long long
#define LLFmt "%lld"

const int maxN = 100 + 3;
const int maxM = 1000 + 3;
int head[100 + 3];
int N, M;

struct EdgeNode
{
    int to;
    int next;
};
EdgeNode Edges[1000 + 3];

struct Edge
{
    int x;
    int y;
};
Edge MM[1000 + 3];

int indegree[100 + 3];

int getIdg()
{
    memset(indegree, 0, sizeof(indegree));
    for(int i = 1; i <= M; i++)
        indegree[ Edges[i].to ]++;
}
void tplgSort()
{
    getIdg();
    stack<int> st;
    for(int i = 1; i <= 5; i++) 
        if( !indegree[i] ) st.push(i);
    while( !st.empty() )
    {
        int tp = st.top();
        cout <<  tp << " ";
        st.pop();

        for(int i = head[ tp ]; i != -1; i = Edges[i].next )
        {
            --indegree[ Edges[i].to ];
            if( !indegree[ Edges[i].to ] ) 
                st.push( Edges[i].to );
        }
    }
}

int main()
{
    //freopen("input.txt", "r", stdin);
    memset(head, -1, sizeof(head));
    
   	int j = 1;
	for (int k = 0; k < 5; k++) {
		int x, arr[10000], len = 0;
		char c;
		while (scanf("%d%c", &x, &c)) {
			arr[len++] = x;
			if (c == '\n') {
			
				for (int i = 1; i < len; i++) {
					MM[j].x = arr[i];
					MM[j++].y = arr[0];
				}
				
				break;
			}
			
		
		}
	}
    for (int i = 1; i < j; i++) {
    	int x = MM[i].x, y = MM[i].y;
        Edges[i].to = y;
        Edges[i].next = head[x];
        head[x] = i;

	}
	M = j;
    
//    for (int i = 0; i < 10; i++) cout << head[i] << " ";
//    cout << endl;
//    
//    for (int i = 1; i < j; i++) {
//    	cout << Edges[i].to << " " << Edges[i].next << endl;
//	}
    tplgSort();
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值