阿里国际笔试 阿里国际笔试题 0407
笔试时间:2025年04月07日 暑期实习
历史笔试传送门:
第一题
题目:数字卡片
小红拥有一系列数字卡片,每张卡片上印有一个数字,这些数字的取值范围为0 ~ 9。每种数字卡片的数量均有限(可能为零),且每张卡片在拼凑新数字时只能被使用一次或不用。小红希望利用手中的卡片拼凑出若干个全新的数字。拼凑过程遵循如下规则:-每个新数字由至少一张卡片组成,卡片上的数字按任意顺序排列后构成该数字-排列顺序决定了新数字的数值大小(不允许存在前导0);请你帮小红计算,她最多可以拼凑出多少个正整数的偶数数字?
输入描述
第一行给出c1,c2..c10 10个整数,其中ci表示数字的卡片数量。
输出描述
输出一个整数,表示最多可以拼凑出多少个正整数的偶数数字。
样例输入
0 3 2 0 0 0 0 0 0 0
样例输出
2
参考题解
答案就是数字2,4,6,8的出现次数加上min(0的出现次数,奇数的出现次数)。
C++:[此代码未进行大量数据的测试,仅供参考]
#include <bits/stdc++.h> usingnamespacestd; int main() { vector<int> a; int num; while (cin >> num) { a.push_back(num); } int res = 0; int cnt = 0; for (int i = 1; i < a.size(); i++) { if (i % 2 == 0) { res += a[i]; } else { cnt += a[i]; } } cout << res + min(cnt, a[0]) << endl; }
Java:[此代码未进行大量数据的测试,仅供参考]
import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); List<Integer> a = new ArrayList<>(); while (scanner.hasNextInt()) { a.add(scanner.nextInt()); } int res = 0; int cnt = 0; for (int i = 1; i < a.size(); i++) { if (i % 2 == 0) { res += a.get(i); } else { cnt += a.get(i); } } System.out.println(res + Math.min(cnt, a.get(0))); } }
Python:[此代码未进行大量数据的测试,仅供参考]
import sys a = list(map(int, sys.stdin.read().split())) res = 0 cnt = 0 for i in range(1, len(a)): if i % 2 == 0: res += a[i] else: cnt += a[i] print(res + min(cnt, a[0]))
第二题
题目:解密字符串
小美有一个由大小写字母混合构成的加密字符串 s,你需要按照以下准则将其解密得到字符串 t。初始时字符串t为空,对于字符串s的每一个字符 si:如果 s 的第 i 个字符为'R’,则反转字符串 t;如果 s 的第 i 个字符为'Z’,则撤销上一步操作,具体地:如果上一步为'R’,则取消反转;如果上一步为'Z’,则取消撤销;如果上一步为其他字符,删除这个字符;上一步为空,则跳过这一操作;其他情况,直接将这个字符添加到字符串t的结尾;请你直接输出解密完成后的字符串 t。
输入描述
每个测试文件均包含多组测试数据。第一行输入一个整数T代表数据组数,每组测试数据描述如下:
第一行输入一个字符串 s 代表加密字符串。
除此之外,保证单个测试文件的字符数量之和不超过 。
输出描述
对于每一组测试数据,新起一行输出解密完成后的字符串t。数据保证字符串长度不为 0。
样例输入
2
ZmeRDZ
DameDame
样例输出
em
DameDame
说明:
对于第一组测试数据,解密过程依次为
第一步为撤销操作,直接跳过
第二步,将"m"加入,t="m"
第三步,将"e"加入,t="me";
第四步,翻转字符串,t="em" ;
第五步,将"D"加入,t="emD"
第六步,删除第五步加入的字母,t="em"。
参考题解
由于可能连续撤销,先对连续的每段Z处理。统计每段连续Z的数量,如果是奇数就相当于一个Z,如果是偶数就相当于不做任何操作。之后考虑用双端队列储存当前字符串序列模拟,并使用栈记录操作历史,同时维护一个flag表示此时是否反转,若flag为false时说明没有反转,此时插入到队尾;否则说明反转了就插入到队首。注意模拟时的细节即可。
C++:[此代码未进行大量数据的测试,仅供参考]
#include <bits/stdc++.h> usingnamespacestd; int main() { int q; cin >> q; cin.ignore(); for (int _ = 0; _ < q; ++_) { string ss; getline(cin, ss); string s; int i = 0; while (i < ss.size()) { if (ss[i] != 'Z') { s += ss[i]; ++i; continue; } int cnt = 1; int j = i + 1; while (j < ss.size() && ss[j] == 'Z') { ++cnt; ++j; } if (cnt % 2 == 1) s += 'Z'; i = j; } deque<char> dq; stack<pair<char, char>> stk; bool flag = false; for (char c : s) { if (c == 'R') { flag = !flag; stk.push({'r', '\0'}); } elseif (c == 'Z') { if (!stk.empty()) { auto pre = stk.top(); stk.pop(); if (pre.first == 'r') { flag = !flag; } elseif (pre.first == 'a') { char pos = pre.second; if (pos == 'f' && !dq.empty()) { dq.pop_front(); } elseif (pos == 'e' && !dq.empty()) { dq.pop_back(); } } } } else { if (flag) { dq.push_front(c); stk.push({'a', 'f'}); } else { dq.push_back(c); stk.push({'a', 'e'}); } } } string res(dq.begin(), dq.end()); if (flag) reverse(res.begin(), res.end()); cout << res << endl; } }
Java:[此代码未进行大量数据的测试,仅供参考]
import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int q = Integer.parseInt(scanner.nextLine()); for (int t = 0; t < q; t++) { String ss = scanner.nextLine(); StringBuilder s = new StringBuilder(); int i = 0; while (i < ss.length()) { if (ss.charAt(i) != 'Z') {
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南