拼多多笔试 拼多多笔试题 0323
笔试时间:2025年03月23日
历史笔试传送门:
第一题
题目:多多的推箱子游戏
多多最近在玩一个推箱子游戏,在一个二维坐标中,箱子的起坐标是 (x,y) ,多多有四个方向键可以操作:***W***:将箱子向上移动,即:(x,y) -> (x, y+1)***A***:将箱子向左移动,即:(x,y) -> (x-1, y)***S***:将箱子向下移动,即:(x,y) -> (x, y-1)***D***:将箱子向右移动,即:(x,y) -> (x+1, y)在经过多多一系列按键操作后,如果恰好最终箱子的位置恰好在 (0,0) 就算赢了,请你帮忙计算多多是否能赢。
输入描述
第一行,包含一个数字T(1 <= T <= 100),表示T组测试用例。
接下来,对于每组测试用例,输入有2行:第1行包含两个数字x和y,表示箱子的起始坐标(x,y)。 -10000 <= x,y <= 10000
第2行包含一个字符串S(由W、A、S、D这4个字母组成),记录了多多的一系列移动操作。字符串的长度大于0且不超过1000
输出描述
对于每组测试用例,输出一个字符串:"YES" 表示赢了, "NO" 表示没有赢。
样例输入
2
2 0
WAS
1 0
WAADS
样例输出
NO
YES
说明:
有2组测试用例:对于第1组用例,起始位置是(2,0),经过W、A、S操作后,位置的变化过程是:-> (2,1) -> (1,1) -> (1, 0),最终位置是(1, 0),所以没有赢,输出NO。对于第2组测试用例,初始位置是(1,0),经过W、A、A、D、S操作后,位置的变化过程是:-> (1,1)-> (0,1)-> (-1,1) -> (0,1) -> (0,0),最终位置是(0,0),所以赢了,输出YES。
参考题解
模拟。输入处理:首先读取输入的测试用例数量 T。对于每个测试用例,读取起始坐标 (x, y) 和操作字符串 S。坐标更新:根据操作字符串中的每个字符更新箱子的位置。使用字典来映射每个操作对应的坐标变化。结果判断:遍历完所有操作后,检查最终的坐标是否为 (0,0),如果是则输出 "YES",否则输出 "NO"。
C++:[此代码未进行大量数据的测试,仅供参考]
#include <iostream> #include <map> #include <string> using namespace std; int main() { int t; cin >> t; map<char, pair<int, int>> directions; directions['W'] = {0, 1}; directions['A'] = {-1, 0}; directions['S'] = {0, -1}; directions['D'] = {1, 0}; while (t--) { int x, y; cin >> x >> y; string s; cin >> s; for (char c : s) { x += directions[c].first; y += directions[c].second; } if (x == 0 && y == 0) { cout << "YES" << endl; } else { cout << "NO" << endl; } } return 0; }
Java:[此代码未进行大量数据的测试,仅供参考]
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int t = sc.nextInt(); Map<Character, int[]> directions = new HashMap<>(); directions.put('W', new int[]{0, 1}); directions.put('A', new int[]{-1, 0}); directions.put('S', new int[]{0, -1}); directions.put('D', new int[]{1, 0}); while (t-- > 0) { int x = sc.nextInt(); int y = sc.nextInt(); String s = sc.next(); for (char c : s.toCharArray()) { x += directions.get(c)[0]; y += directions.get(c)[1]; } if (x == 0 && y == 0) { System.out.println("YES"); } else { System.out.println("NO"); } } } }
Python:[此代码未进行大量数据的测试,仅供参考]
t = int(input()) directions = { 'W': (0, 1), 'A': (-1, 0), 'S': (0, -1), 'D': (1, 0) } for _ in range(t): x, y = map(int, input().split()) s = input().strip() for c in s: dx, dy = directions[c] x += dx y += dy if x == 0 and y == 0: print("YES") else: print("NO")
第二题
题目:多多买彩票
多多的家乡最近推出了一种新型彩票,规则非常有趣:如果一个数字中,隐藏着一个连续的子串,且这个子串代表的数是3的倍数,那么这个数字就是“幸运数字”。彩票每期都会公布一个范围[L, R],并从这个范围的“幸运数字”中随机选择一个作为中奖号码。以下是一些例子,辅助理解“幸运数字”的含义:107是“幸运数字”:0是107的子串,且0是3的倍数25不是“幸运数字”:25有3个子串分别是2、5、25,它们都不是3的倍数2521是“幸运数字”:21是2521的子串,且21是3的倍数注意子串必须是连续的,例:在数字152中,15是子串,12不是子串
以0开头的子串需要抹去先导0来考虑数值,例:在数字103中,03是一个子串,它的值为3,也是3的倍数多多想知道[L, R]中有多少个幸运数字,你能帮帮他吗?
输入描述
有多个测试用例。输入的第一行包含一个整数T(1<=T<=10000),表示测试用例的数量;
每组输入仅一行,包含两个整数L,R(1<=L<=R<=1e18)
输出描述
对每个测试用例,输出一个整数,表示区间[L,R]中“幸运数字”的个数。
样例输入
2
8 19
2 45
样例输出
8
31
参考题解
题目要求找出区间[L, R]中所有幸运数字的个数。幸运数字的定义是存在一个连续子串表示的数是3的倍数。直接计算幸运数字比较复杂,可以考虑计算非幸运数字的数量,然后用总数减去非幸运数字的数量得到幸运数字的数量。非幸运数字是指其所有连续子串都不满足是3的倍数。根据数论知识,一个数是3的倍数当且仅当其各位数字之和是3的倍数。对于一个数来说,如果其所有长度为1、2、3的子串都不满足各位数字之和是3的倍数,那么该数就是非幸运数字。因为对于长度大于3的数,根据鸽巢原理,必然存在一个长度为3的子串各位数字之和是3的倍数。预处理所有小于1000的数,判断哪些是非幸运数字,并记录它们的前缀和。因为对于大于等于1000的数,必然存在一个长度为3的子串各位数字之和是3的倍数,所以这些数都不是非幸运数字。对于给定的区间[L, R],计算该区间内非幸运数字的数量,然后用总数(R-L+1)减去非幸运数字的数量得到幸运数字的数量。利用预处理的前缀和数组,可以快速计算任意区间内的非幸运数字数量,总数减去非幸运数字数量即为幸运数字数量。
C++:[此代码未进行大量数据的测试,仅供参考]
#include <iostream> #include <vector> #include <set> using namespace std; vector<int> get_digits(int x) { if (x == 0) { return {0}; } vector<int> digits; while (x > 0) { digits.push_back(x % 10); x /= 10; } reverse(digits.begin(), digits.end()); return digits; } bool is_unlucky(int x) { if (x == 0) { return false; } vector<int> digits = get_digits(x); set<int> seen; int total = 0; for (int d : digits) { total += d; int mod = total % 3; if (mod == 0) { return false; } if (seen.find(mod) != seen.end()) { return false; } seen.insert(mod); } return true; } int main() { int T; cin >> T; const int max_small = 1000; vector<bool> is_unlucky_list(max_small, false); int unlucky_count = 0; for (int i = 0; i < max_small; i++) { if (is_unlucky(i)) { is_unlucky_list[i] = true; unlucky_count++; } } vector<int> prefix_unlucky(max_small, 0); prefix_unlucky[0] = is_unlucky_list[0] ? 1 : 0; for (int i = 1; i < max_small; i++) { prefix_unlucky[i] = prefix_unlucky[i - 1] + (is_unlucky_list[i] ? 1 : 0); } while (T--) { int L, R; cin >> L >> R; auto compute = [&prefix_unlucky, &unlucky_count](int x) { if (x >= 999) { return x + 1 - unlucky_count; } else { if (x < 0) { return 0; } return (x + 1) - prefix_unlucky[x]; } }; int fR = compute(R); int fL_1 = compute(L - 1); cout << fR - fL_1 << endl; } return 0; }
Java:[此代码未进行大量数据的测试,仅供参考]
import java.util.*; public class Main { public static List<Integer> getDigits(int x) { if (x == 0) { return Arrays.asList(0); } List<Integer> digits = new ArrayList<>(); while (x > 0) { digits.add(x % 10); x /= 10; } Collections.reverse(dig
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南