携程笔试 携程笔试题 0919
笔试时间:2024年09月19日 秋招
历史笔试传送门:2023秋招笔试合集
第一题
题目
一个nxm 的网格图a,左上角为(0,0),右下角为(n-1,m-1),格子(i,j) 价值为 i * m + j。游游从左上角 (0,0)为起点,每一步可以走到上下左右四个方向的相邻格子。每到达一个格子,就能获取相应格子的奖励。需要注意的是,在到达某个格子获取宝物后,这个格子的宝物会在游游离开格子后再次刷新。现在给出一个整数k,表示游游最多走k步。问:游游最多能获得多少价值的宝物
输入描述
第一行输入q(1 <= q <= 10 ^ 5),表示询问个数。
接下来q行,每行输入n,m,k(1 <= n, m, k <= 10^4, n + m > 2),表示矩阵大小和限制步数。
输出描述
输出q行分别表示每组数据答案。
样例输入
1
2 2 5
样例输出
12
参考题解
模拟。
C++:[此代码未进行大量数据的测试,仅供参考]
#include <bits/stdc++.h> using namespace std; #define ll long long void solve() { int n, m, k; cin >> n >> m >> k; ll ans = 0; if (k >= n - 1) { k -= n - 1; ans += 1LL * (n - 1) * m * n / 2; }else { ans += 1LL * k * m * (k + 1) / 2; k = 0; } int last = (n - 1) * m; if (k >= m - 1) { ans += 1LL * (last + 1 + last + m - 1) * (m - 1) / 2; k -= m - 1; }else { ans += 1LL * (last + 1 + last + k) * k / 2; k = 0; } last = n * m - 1; int prev = last - 1; if (k > 0) { ans += 1LL * (k + 1) / 2 * prev; ans += 1LL * k / 2 * last; } cout << ans << "\n"; } int main() { int t; cin >> t; while (t--) { solve(); } }
Java:[此代码未进行大量数据的测试,仅供参考]
import java.util.Scanner; public class Solution { public static void solve() { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int m = sc.nextInt(); int k = sc.nextInt(); long ans = 0; if (k >= n - 1) { k -= n - 1; ans += 1L * (n - 1) * m * n / 2; } else { ans += 1L * k * m * (k + 1) / 2; k = 0; } int last = (n - 1) * m; if (k >= m - 1) { ans += 1L * (last + 1 + last + m - 1) * (m - 1) / 2; k -= m - 1; } else { ans += 1L * (last + 1 + last + k) * k / 2; k = 0; } last = n * m - 1; int prev = last - 1; if (k > 0) { ans += 1L * (k + 1) / 2 * prev; ans += 1L * k / 2 * last; } System.out.println(ans); } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int t = sc.nextInt(); while (t-- > 0) { solve(); } } }
Python:[此代码未进行大量数据的测试,仅供参考]
def solve(): n, m, k = map(int, input().split()) ans = 0 if k >= n - 1: k -= n - 1 ans += (n - 1) * m * n // 2 else: ans += k * m * (k + 1) // 2 k = 0 last = (n - 1) * m if k >= m - 1: ans += (last + 1 + last + m - 1) * (m - 1) // 2 k -= m - 1 else: ans += (last + 1 + last + k) * k // 2 k = 0 last = n * m - 1 prev = last - 1 if k > 0: ans += (k + 1) // 2 * prev ans += k // 2 * last print(ans) def main(): t = int(input()) for _ in range(t): solve() if __name__ == "__main__": main()
第二题
题目
游游在黑板上写下了n个数字,构成了一个可重集合。游游请你参与一个游戏:每轮操作你可以任选集合中最大值和最小值的差不超过k的 m 个数字,然后删去这 m 个数字中的最小值(删除一个),并把其他的数字放回集合中。若无法选出符合条件的m个数,则无法继续操作。你可以无限次进行这个操作,直到没法操作为止。要使得最后留下的数最少,请你求出操作后留下的最少的数字数量。
输入描述
第一行三个整数n,m,k(2 <= m <= 10^6, 0 <= k <= 10^9)
第二行输入n个整数。
输出描述
输出答案。
样例输入一
4 3 3
1 2 3 6
样例输出一
3
样例输入二
5 3 2
5 4 4 2 1
样例输出二
3
样例输入三
7 2 0
3 3 3 3 4 4 4
样例输出三
2
参考题解
对数组进行排序然后维护一个长度为m的窗口即可。
C++:[此代码未进行大量数据的测试,仅供参考]
#include <bits/stdc++.h> using namespace std; int main() { int n, m, k; cin >> n >> m >> k; vector<int> a(n); for (int i = 0; i < n; i++) { cin >> a[i]; } sort(a.begin(), a.end()); int ans = n; for (int l = 0, r = 0; r < n; r++) { if (r - l + 1 == m) { if (a[r] - a[l] <= k) { ans--; } l++; } } cout << ans << "\n"; }
Java:[此代码未进行大量数据的测试,仅供参考]
import java.util.*; public class Solution { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int m = sc.nextInt(); int k = sc.nextInt(); int[] a = new int[n]; for (int i = 0; i < n; i++) { a[i] = sc.nextInt(); } Arrays.sor
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
持续收录字节、腾讯、阿里、美团、美团、拼多多、华为等笔试题解,包含python、C++、Java多种语言版本,持续更新中。