饿了么笔试 饿了么秋招 0912
笔试时间:2025年9月12日
往年笔试合集:
第一题
给定整数 n、m、k,请你在 n 行 m 列的网格中填入整数,使得:
- 每个格子填入的整数在 1 到 k 之间
- 每个整数恰好出现 (n*m)/k 次
- 对于每个 i (1≤i≤k),编号为 i 的格子构成的连通块(基于四相邻)是连通的
输入描述
第一行输入一个整数 t (1≤t≤500),表示测试用例数。 接下来 t 行,每行输入三个整数 n、m、k,满足 1≤n,m≤100、1≤k≤nm 且 nm 能被 k 整除。
输出描述
对于每个测试用例,输出 n 行,每行 m 个整数,表示一种满足条件的网格填充方案。
样例输入
2
2 2 2
2 4 2
样例输出
1 1
2 2
1 1 1 1
2 2 2 2
第一组输出中,1 和 2 各出现 2 次,且编号相同的格子各自构成基于 4 邻接的连通块; 第二组输出中,1 和 2 各出现 4 次,且编号相同的格子各自构成基于 4 邻接的连通块。
参考题解
解题思路:
使用蛇形遍历保证连通性。将网格按蛇形路径(第一行从左到右,第二行从右到左,交替进行)遍历,然后将整个路径分成 k 段,每段长度为 (n*m)/k,每段填充同一个数字。这样相同数字的格子必然在路径上连续,因此它们在网格中也一定是连通的。
C++:
#include <iostream> #include <vector> using namespace std; void solve() { int n, m, k; cin >> n >> m >> k; int cells_per_num = (n * m) / k; vector<vector<int>> grid(n, vector<int>(m, 0)); int current_num = 1; int count_for_current_num = 0; for (int i = 0; i < n; i++) { if (i % 2 == 0) { for (int j = 0; j < m; j++) { grid[i][j] = current_num; count_for_current_num++; if (count_for_current_num == cells_per_num && current_num < k) { current_num++; count_for_current_num = 0; } } } else { for (int j = m - 1; j >= 0; j--) { grid[i][j] = current_num; count_for_current_num++; if (count_for_current_num == cells_per_num && current_num < k) { current_num++; count_for_current_num = 0; } } } } for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cout << grid[i][j]; if (j < m - 1) cout << " "; } cout << "\n"; } } int main() { int t; cin >> t; while (t--) { solve(); } return 0; }
Java:
import java.util.*; public class Main { public static void solve(Scanner sc) { int n = sc.nextInt(); int m = sc.nextInt(); int k = sc.nextInt(); int cellsPerNum = (n * m) / k; int[][] grid = new int[n][m]; int currentNum = 1; int countForCurrentNum = 0; for (int i = 0; i < n; i++) { if (i % 2 == 0) { for (int j = 0; j < m; j++) { grid[i][j] = currentNum; countForCurrentNum++; if (countForCurrentNum == cellsPerNum && currentNum < k) { currentNum++; countForCurrentNum = 0; } } } else { for (int j = m - 1; j >= 0; j--) { grid[i][j] = currentNum; countForCurrentNum++; if (countForCurrentNum == cellsPerNum && currentNum < k) { currentNum++; countForCurrentNum = 0; } } } } for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { System.out.print(grid[i][j]); if (j < m - 1) System.out.print(" "); } System.out.println(); } } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int t = sc.nextInt(); for (int i = 0; i < t; i++) { solve(sc); } sc.close(); } }
Python:
import sys def solve(): n, m, k = map(int, sys.stdin.readline().split()) cells_per_num = (n * m) // k grid = [[0] * m for _ in range(n)] current_num = 1 count_for_current_num = 0 for i in range(n): if i % 2 == 0: columns_iterator = range(m) else: columns_iterator = range(m - 1, -1, -1) for j in columns_iterator: grid[i][j] = current_num count_for_current_num += 1 if count_for_current_num == cells_per_num and current_num < k: current_num += 1 count_for_current_num = 0 for row in grid: print(*row) t = int(sys.stdin.readline()) for _ in range(t): solve()
第二题
给定三个整数 a、b、c,你可以且必须恰好执行一次如下操作:选择一个整数 t,并将 a、b、c 中恰好一个数乘以 t。完成上述操作后,你可以对这三个数进行任意重排。请判断是否存在一种选择,使得最终得到的三个数可以重排成一个等比数列。
输入描述
每个测试文件均包含多组测试数据。第一行输入一个整数 t (1≤t≤500) 代表数组组数。 每组测试数据:在一行上输入三个整数 a,b,c (-10^9≤a,b,c≤10^9)。
输出描述
对于每一组测试数据,新起一行。若存在可行方案,输出 YES;否则输出 NO。
样例输入
4
2 3 6
1 2 3
2 4 8
5 1 25
样例输出
YES
NO
YES
YES
参考题解
解题思路:
等比数列的特点是中间项的平方等于两边项的乘积。枚举修改哪个数(a、b或c),然后检查是否存在整数t使得修改后的三个数能构成等比数列。对于每种修改情况,考虑修改后的数在等比数列中的位置(首项、中项或末项),利用等比数列的性质求出所需的t值并检查是否为整数。
C++:
#include <iostream> #include <cmath> using namespace std; bool check(long long p, long long q, long long r) { // 可能性1: q是中间项 if ((q * q) % r == 0) { long long new_p = (q * q) / r; if (new_p % p == 0) return true; } // 可能性2: r是中间项 if ((r * r) % q == 0) { long long new_p = (r * r) / q; if (new_p % p == 0) return true; } // 可能性3:
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南