小美的蛋糕切割(美团2024届秋招笔试第一场编程真题)

这篇文章讨论了如何使用二维前缀和数组来解决切蛋糕问题,通过计算矩阵的和并枚举切割位置,快速找到两个矩形区域的最小差值,以求得最优切割方案。

题目分析:切蛋糕问题切记可以横着切,也可以竖着切。本题目需要快速求得两个矩形的和,可以用二维前缀和数组解决。然后枚举一刀切的位置。

#include <iostream>
#include <algorithm>
using namespace std;
int a[1005][1005];
long long sum[1005][1005];/**< 注意到数据范围可能超过int */
int main()
{
    int i,j,n,m;
    cin>>n>>m;
    for(i=1;i<=n;i++)
        for(j=1;j<=m;j++){
            cin>>a[i][j];/**< 二维前缀和数组常见求法 */
            sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];
        }
    long long ans=sum[n][m];
    /**< 枚举蛋糕切割,注意可以横着也可以竖着切 */
    for(i=1;i<n;i++)
        ans=min(ans,abs(sum[i][m]-(sum[n][m]-sum[i][m])));/**<sum[i][m]上半块蛋糕  */
    for(j=1;j<m;j++)
        ans=min(ans,abs(sum[n][j]-(sum[n][m]-sum[n][j])));/**<sum[n][j]左半块蛋糕  */
    cout<<ans;
    return 0;
}

解释下:sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];作用

美团笔试算法题目汇总如下: - **2021春招笔试题 - 学生值日问题**:小美和小团的班上有n个人,分别编号为1到n,小美的编号为1,小团的编号为2。给定一个n×n的矩阵`duty`,用于确定每天值日的学生。第一天小美值日,第二天小团值日,从第三天开始,第i天值日的学生编号由`duty[a2 - 1][a1 - 1]`确定,其中`a1`是前一天值日学生的编号,`a2`是当天值日学生的编号。要求根据输入的天数m,计算并输出第m天值日学生的编号。示例输入:`3 7`,`0 3 2`,`3 0 3`,`2 1 0` [^1]。 ```java package MT; import java.util.Scanner; public class MT4 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int m = sc.nextInt(); int[][] duty = new int[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { duty[i][j] = sc.nextInt(); } } System.out.println(studentID(m, duty)); } static int studentID(int m, int[][] dutyTable) { int id = 0; int a1 = 1, a2 = 2; int i = 0; while (i < (m - 2)) { id = dutyTable[a2 - 1][a1 - 1]; a1 = a2; a2 = id; i++; } return id; } } ``` - **美团笔试题目 - 深度优先搜索问题**:给定一个二维数组`a`,通过深度优先搜索(DFS)遍历数组元素。根据不同的边界条件,递归调用`dfs`函数进行元素的输出和继续搜索。当数组长度为0时返回 -1,否则通过`dfs`函数进行搜索后返回1 [^2]。 ```java public static int solve(int[][] a) { int N = a.length; if (N == 0) return -1; dfs(a, 0, N - 1, N); return 1; } public static void dfs(int[][] arr, int row, int col, int N) { if (row < N - 1 && col == N - 1) { System.out.println(arr[row][col]); dfs(arr, 0, N - row - 2, N); return; } if (row == N - 1 && col == N - 1) { System.out.println(arr[row][col]); dfs(arr, 1, 0, N); return; } if (row == N - 1 && col < N - 1 && col > 0) { System.out.println(arr[row][col]); dfs(arr, N - col, 0, N); return; } if (row == N - 1 && col == 0) { System.out.println(arr[row][col]); return; } System.out.print(arr[row][col]); System.out.print(" "); dfs(arr, row + 1, col + 1, N); return; } ``` - **2024 - 03 - 23美团春招笔试题**:包含多个问题,如K小姐的华丽灯光秀、K小姐的字符串修改、A先生的玩具摆放、K小姐的密码设计、LYA小姐的花园整理、K小姐的树林漫步等。每个问题都有相应的问题描述、输入格式、输出格式、样例输入、样例输出、数据范围和题解及参考代码 [^3]。 - **美团笔试 - 数字查找问题**:给定一个长度不超过1000的字符串,字符串仅由数字字符组成。要求找出未出现过的最小正整数,如果所有1 - 9的数字都出现过,则找出出现次数最少的数字,若有多个数字出现次数最少,则输出其中最小的数字,若所有数字都出现过且出现次数相同,则输出1后面跟和出现次数相同数量的0 [^4]。 ```cpp #include <iostream> #include <string.h> using namespace std; int main() { char c[1001]; int su = 0, num[10]; for (int i = 0; i < 10; i++) num[i] = 0; cin >> c; int len = strlen(c); for (int i = 0; i < len; i++) num[c[i] - '0']++; for (int i = 1; i <= 9; i++) if (!num[i]) { cout << i; return 0; } if (!num[0]) { cout << 1 << 0; return 0; } int minn = 10000; for (int i = 0; i <= 9; i++) if (minn > num[i]) minn = num[i]; for (int i = 1; i <= 9; i++) if (num[i] == minn) { while (minn--) cout << i; cout << i; return 0; } cout << 1; while (minn--) cout << 0; cout << 0; return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值