2023 字节笔试题 0820
笔试时间:2023年8月20日 秋招
第一题
题目
小红将n个珠子排成一排,然后将它们串起来,连接成了一串项链(连接后为一个环,即第一个和最后一个珠子也是相邻的),任意相邻两个珠子的距离为1。已知初始共有3个珠子是红色的,其余珠子是白色的。小红拥有无穷的魔力,她可以对项链上的相邻两个珠子进行交险。小红希望用最小的交换次数,使得红意两个红色的珠子的最小阳距离小干k,你能帮小红求出最小的交换次数吗?
输入描述
第一行输入一个正些数t,代表询问次数。
每行为一次询间,输出五个正整数n,k,a1,a2,a3,分别代表珠子总数量,要求的珠子距离,以及三个珠子的位置。
1<=t<=10^4
1<=n<=10^9
1<=k,a1,a2,a3<=n
保证ai互不相同。
输出描述
输出t行,每行输入一个整数,代表最小的交换次数。如果无法完成目的,则输出-1。
样例输入
2
6 2 1 2 3
5 2 1 3 4
样例输出
2
-1
第一组样例,六个珠子为红红红白白白。第一次操作交换第一个和第六个珠子,第二次操作交换第三个和第四个珠子。
第二组询问,一共有5个珠子,其中有3个红珠子,因此无论如何都会有两个红珠子相邻,不可能满足任意两个红珠子的最小距离不小于2。
参考题解
使用一个数组记录三个红色珠子彼此的距离,然后循环判断调整哪两个珠子距离交换次数最少,每次调整后排序直到输出正确结果,如果数组太小没操作空间直接输出-1
C++:
#include <iostream>
#include <string>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
vector<int> p(3);
vector<int> q(3);
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
int m, k, x, y, z;
cin >> m >> k >> x >> y >> z;
p[0] = x;
p[1] = y;
p[2] = z;
sort(p.begin(), p.end());
if (3ll * k > m)
{
cout << -1 << endl;
continue;
}
q[0] = p[1] - p[0];
q[1] = p[2] - p[1];
q[2] = p[0] + m - p[2];
sort(q.begin(), q.end());
ll ans = 0;
while (q[0] < k)
{
int now = min(k - q[0], q[2] - k);
ans += now;
q[2] -= now;
q[0] += now;
sort(q.begin(), q.end());
}
cout << ans << endl;
}
return 0;
}
Java:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
for (int i = 0; i < n; i++) {
int m = sc.nextInt();
int k = sc.nextInt();
int x = sc.nextInt();
int y = sc.nextInt();
int z = sc.nextInt();
ArrayList<Integer> p = new ArrayList<>();
p.add(x);
p.add(y);
p.add(z);
Collections.sort(p);
if (3 * k > m) {
System.out.println(-1);
continue;
}
ArrayList<Integer> q = new ArrayList<>();
q.add(p.get(1) - p.get(0));
q.add(p.get(2) - p.get(1));
q.add(p.get(0) + m - p.get(2));
Collections.sort(q);
long ans = 0;
while (q.get(0) < k) {
int now = Math.min(k - q.get(0), q.get(2) - k);
ans += now;
q.set(2, q.get(2) - now);
q.set(0, q.get(0) + now);
Collections.sort(q);
}
System.out.println(ans);
}
}
}
Python:
n = int(input())
for _ in range(n):
m, k, x, y, z = map(int, input().split())
p = [x, y, z]
p.sort()
if 3 * k > m:
print(-1)
continue
q = [p[1] - p[0], p[2] - p[1], p[0] + m - p[2]]
q.sort()
ans = 0
while q[0] < k:
now = min(k - q[0], q[2] - k)
ans += now
q[2] -= now
q[0] += now
q.sort()
print(ans)
第二题
题目
小红最近迷上了纸牌。纸牌有黑桃(Spade)、红桃(Heart)、方块 (Diamond) 、梅花(Club) 四种花色,并且每张纸牌上面写了一个正整数。小红拿到了许多牌,准备玩以下游戏:
每次操作在这堆牌中任取5张牌,计算这5张牌的分数,然后将其丢弃(丢弃的牌不可再次选取)。
为了简化,本题仅计算同花顺这一牌型:即取出的5张牌构成同花顺,则可以获得1分。其他牌型均不得分。
所谓同花顺,即五张牌花色相同,且排序后满足 ai+1=a(i+l)。
小红想知道,经过若干次操作后,自己最多可以得到多少分?
请注意,同一个牌型可能出现多次!
输入描述
第一行输入一个正整教n,代表牌堆中牌的种类(如果两张牌的花色或数值不同,则认为种类不同)。
接下来的n行,每行输入两个正整教:ai和cnti和一个字符ci。分别代表每种牌的大小、数量以及花色。
1<=n<=10^5
1<=ai,cnti<=10^9
ci∈{'s','H','D','C'},代表扑克牌的四种花色: 黑桃(Spade)、红桃(Heart)、方块(Diaond)、梅花(Club)。
保证每个种类的牌在输入中只出现了一次。
输出描述
一个整数,代表小红可以最多获得的分数。
样例输入
6
1 1 s
2 2 s
3 2 s
4 2 s
5 2 s
1 10 h
样例输出
1
可以取到一个同花顺:[1S,2S,3S,4S,5S]。虽然有10个红桃1,但无法和其他牌凑成同花顺。
参考题解
设置一个结构体,分别set去重,map记录次数。用map记录每个输入卡牌对应的花色和数量。遍历各个花色,记录花色同花顺的个数并累加。输出最终结果。
C++:
#include <iostream>
#include <string>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
struct node
{
set<int> st;
map<int, ll> cnt;
};
map<string, node> mp;
string cards[] = {"H","S","D","C"};
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
int x, y;
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
2023秋招各大笔试题汇总,c++,java,python多种语言分析,解答。

查看13道真题和解析