9.18 字节笔试编程题题解

// 先占个坑,笔试结束发题解。
总的来说,4题都不难,甚至第4题30分还是力扣中等题。
1.
给你一些盘子,每个盘子有一个编号,你需要将这些盘子按顺序收拾起来。
盘子叠放后被分成多个堆,每个堆可能由一个或多个盘子组成。
叠放在同一堆的盘子的序号都是不间断递增的,并且盘子数量至少是3个

输入:一个固定长度的递增整数数组
输出:一个字符串,每个堆被逗号分隔开,如果堆中只有一个盘子,就用序号表示。
如果堆中有多个盘子,用 [起始编号]-[终止编号] 表示

示例:
输入:[-3,-2,-1,2,10,15,16,18,19,20]   (这里不是直接输入整数,可能有些同学不会处理IO...,可以学一下,华为笔试题IO就是这种风格)
输出: -3--1,2,10,15,16,18-20
#include <bits/stdc++.h>
using namespace std;

int main() {
    vector<int> v;
    char c;
    int x;
    while (~scanf("%c", &c) && c != ']') {
        scanf("%d", &x);
        v.push_back(x);
    }
    const int n = v.size();
    for (int i = 0; i < n; i++) {
        int j = i;
        while (j+1 < n && v[j+1] == v[j]+1) j++;
        if (j-i+1 >= 3) {
            printf("%d-%d", v[i], v[j]);
        } else {
            if (i == j) {
                printf("%d", v[i]);
            } else {
                printf("%d,%d", v[i], v[j]);
            }
        }
        i = j;
        if (i < n-1) putchar(',');
    }
    return 0;
}

2.  题目太长了,我不想写。思路就是:自底向上模拟一遍就完事了,动态更新下面一层能够存在的砖头。
#include <bits/stdc++.h>
using namespace std;

int main() {
    int n; cin >> n;
    if (n == 0) {
        cout << 0 << endl;
        return 0;
    }
    int p, m;
    cin >> m;
    int ans = m;
    vector<int> lstLevel;
    for (int i = 0; i < m; i++) {
        cin >> p;
        lstLevel.push_back(p);
    }

    for (int i = 1; i < n; i++) {
        cin >> m;
        vector<int> t;
        for (int j = 0; j < m; j++) {
            cin >> p;   
            int pr = p+100, pm = p+50;
            auto idx = lower_bound(lstLevel.begin(), lstLevel.end(), p) - lstLevel.begin();
            bool ok = false;
            if (idx < lstLevel.size() && lstLevel[idx] < pm) ok = true;
            else if (idx && pm < lstLevel[idx-1]+100) ok = true;
            else if (idx < lstLevel.size() && pr > lstLevel[idx] && idx && lstLevel[idx-1]+100 > p) ok = true;
            if (ok) {
                ans ++;
                t.push_back(p);
            }
        }
        lstLevel = std::move(t);
    }
    cout << ans << endl;
    return 0;
}
3.
给定一个只包含0和1的正整数序列,求最长神奇数列的长度。
神奇数列是指没有相邻两个数相同且长度至少是3的数列。如10101,010

输入:一行连续的数,只有0和1
输出:神奇数列的长度

// 思路没啥好讲的,扫一遍就行了,很简单
#include <bits/stdc++.h>
using namespace std;

int main() {
    string s; cin >> s;
    const int n = s.length();
    int ans = 0;
    for (int i = 0; i < n; i++) {
        int j = i;
        while (j+1 < n && s[j+1] != s[j]) j++;
        if (j-i+1 >= 3)
            ans = max(ans, j-i+1);
        i = j;
    }
    cout << ans << endl;
    return 0;
}    
4.    经典二分+前缀和,考过很多了。
给定一个长度为4倍数的字符串,只由ASDF四个字母构成,要求替换一个子串使整个串中4个字母的个数一同。
求满足要求的最小子串长度

输入:一个字符串
输出:满足条件的最小字串长度

示例1:
输入: ADDF
输出: 1
示例2:
输入:ASAFASAFADDD
输出:3 (替换AFA)
//  C++ 版本
#include <bits/stdc++.h>
using namespace std;

int main() {
    string s; cin >> s;
    const int n = s.length();
    int target = n/4;
    vector<int> cnt(4);
    vector<vector<int>> ps(n+1, vector<int>(4));
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < 4; j++) ps[i][j] = ps[i-1][j];
        if (s[i-1] == 'A') ps[i][0] ++;
        if (s[i-1] == 'S') ps[i][1] ++;
        if (s[i-1] == 'D') ps[i][2] ++;
        if (s[i-1] == 'F') ps[i][3] ++;
    }

    auto ck = [&] (int m) -> bool {
        for (int i = 1; i <= n-m+1; i++) {
          // 除了i开始长度为m的连续子串,设其为s,整个串中剩下的字符个数。因为s中的字母可以替换成任意字符,所以只需要剩下的字符个数不超过目标个数就行。
            vector<int> t(4);
            for (int k = 0; k < 4; k++) t[k] = ps[n][k] - ps[i+m-1][k] + ps[i-1][k];
            if (*max_element(t.begin(), t.end()) <= target) return true;
        }
        return false;
    };

    int ans = n;
    int l = 1, r = n;
    while (l <= r) {
        int m = (l+r)/2;
        if (ck(m)) {
            ans = m;
            r = m-1;
        } else {
            l = m+1;
        }
    }
    cout << ans << endl;
    return 0;
}
// Go 语言版本
package main

import "fmt"

func balancedString(s string) int {
	n := len(s)
	ps := make([][]int, n+1)
	for i := range ps {
		ps[i] = make([]int, 4)
	}
	for i, c := range s {
		for j := range ps[i] {
			ps[i+1][j] = ps[i][j]
		}
		if c == 'A' {
			ps[i+1][0] += 1
		}
		if c == 'S' {
			ps[i+1][1] += 1
		}
		if c == 'D' {
			ps[i+1][2] += 1
		}
		if c == 'F' {
			ps[i+1][3] += 1
		}
	}
	if ps[n][0] == ps[n][1] && ps[n][0] == ps[n][2] && ps[n][0] == ps[n][3] {
		return 0
	}
	ck := func(m int) bool {
		for i := 1; i <= n-m+1; i++ {
			t := make([]int, 4)
			for j := range t {
				t[j] = ps[n][j] - ps[i+m-1][j] + ps[i-1][j]
			}
			if max(max(t[0], t[1]), max(t[2], t[3])) <= n/4 {
				return true
			}
		}
		return false
	}
	l, r, ans := 1, n, n
	for l <= r {
		m := (l + r) / 2
		if ck(m) {
			ans = m
			r = m - 1
		} else {
			l = m + 1
		}
	}
	return ans
}
func max(a, b int) int {
	if a >= b {
		return a
	}
	return b
}
func main() {
	var s string
	fmt.Scan(&s)
	fmt.Println(s)
	fmt.Println(balancedString(s))
}





#字节跳动笔试##字节笔试##字节跳动23秋招笔试心得体会#
全部评论
叠盘子不知道为啥只过50,说我格式有问题,神奇序列A,asdf是lc1234原题,但是只过90,金字塔直接蒙总数-2过了23%
2 回复 分享
发布于 2022-09-18 12:03 安徽
多少分进面试还是说看排名
1 回复 分享
发布于 2022-09-18 12:06 广东
第二题被卡常了
1 回复 分享
发布于 2022-09-18 12:18 江西
寄,一题没a
点赞 回复 分享
发布于 2022-09-18 11:54 湖南
金字塔 92.5 神奇序列100 asdf 5 最后一个10
点赞 回复 分享
发布于 2022-09-18 11:57 陕西
a了3.8,最后一题卡80%不知道为啥
点赞 回复 分享
发布于 2022-09-18 11:58 上海
3.92
点赞 回复 分享
发布于 2022-09-18 11:59 北京
100 80 30 0
点赞 回复 分享
发布于 2022-09-18 12:00 福建
蹲个Construction complete题解,只过了61%
点赞 回复 分享
发布于 2022-09-18 12:01 广东
3.1
点赞 回复 分享
发布于 2022-09-18 12:02 上海
50 15 100 100
点赞 回复 分享
发布于 2022-09-18 12:02 广东
77 100 80 60 第一题后面大概知道咋不暴力了写完有bug但没时间调试了
点赞 回复 分享
发布于 2022-09-18 12:02 广东
金字塔 38 神奇序列70 asdf 95 最有一题0, 大佬们金字塔啥思路啊
点赞 回复 分享
发布于 2022-09-18 12:03 北京
叠盘子的数组怎么输入啊,搞了半小时没搞定。
点赞 回复 分享
发布于 2022-09-18 12:03 广东
100 33 100 100
点赞 回复 分享
发布于 2022-09-18 12:07 陕西
金字塔A了。就是看每一层的每个块的重心和上一层的每个块重心符不符合支撑的三种情况,都不满足的话就丢掉那一块。然后不用每次都和上一层的所有块比,用二分来优化
点赞 回复 分享
发布于 2022-09-18 12:11 日本
100 100 100 10
点赞 回复 分享
发布于 2022-09-18 12:11 广东
80 100 100 80
点赞 回复 分享
发布于 2022-09-18 12:11 新加坡
50,100,100,100,第一个不知道为什么过不了
点赞 回复 分享
发布于 2022-09-18 12:18 江苏
我的第四题怎么是单调队列的
点赞 回复 分享
发布于 2022-09-18 12:22 湖南

相关推荐

评论
18
52
分享
牛客网
牛客企业服务