拼多多笔试 拼多多笔试题 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等多种语言做法集合指南

