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多种语言分析,解答。