个人简介
在读大二,区域赛打铁。
1 订班服
题目描述
小A班级订班服了! 可是小A是个小糊涂鬼,整错了好多人的衣服的大小。 小A只能自己掏钱包来补钱了。 小A想知道自己至少需要买多少件衣服。
思路
计数,找出少买的数量。
代码
// 将尺码字符串映射成数字,方便操作
int map(const std::string& size) {
switch (size[0]) {
case 'M':
return 0;
case 'S':
return 1;
case 'L':
return 2;
default:
return 1 + size.length();
}
}
std::string solution(int n, std::vector<std::string>& arr1, std::vector<std::string>& arr2){
std::string result;
int cnt[8]{};
for (int i = 0; i < arr1.size(); ++i) {
// 统计应买的数量
++cnt[map(arr1[i])];
}
for (int i = 0; i < arr2.size(); ++i) {
// 如果买了 1 件对应衣服,就对应衣服的应买数量减 1
--cnt[map(arr2[i])];
}
int ans = 0;
for (int i = 0; i < 8; ++i) {
// 统计漏买的数量
ans += std::max(0, cnt[i]);
}
// 将答案转换为字符串
char buf[256];
sprintf(buf, "%d", ans);
result = std::string(buf);
return result;
}
2 异或和
题目描述
小张找到了一个整数 N,他想问问你从 1 到 N 的所有不同整数的异或和是多少, 请你回答他的问题。
思路
暴力
代码
int solution(int N){
int result = 0;
for (int i = 1; i <= N; ++i) {
result ^= i;
}
return result;
}
3 零钱兑换
题目描述
给定数组arr,arr中所有的值都为正整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱数,求组成aim的最少货币数。 如果无解,请返回-1. 数据范围:数组大小满足 0 <= n<=10000 , 数组中每个数字都满足 0 < val <=10000,0 <= aim <=100000 要求:时间复杂度 O(n×aim) ,空间复杂度 O(aim)。
思路
动态规划。dp数组为,最少张数[前i种面值][组成j块钱]。
dp方程见代码。
通过滚动数组减少空间消耗。
代码
// 读取输入
struct Input {
std::vector<int> arr;
int aim;
};
Input read(const std::string& input) {
Input in;
int i = 1;
int val = 0;
while (input[i] != ']') {
if (',' == input[i]) {
in.arr.emplace_back(val);
val = 0;
} else {
val = 10 * val + input[i] - '0';
}
++i;
}
if (val > 0) {
in.arr.emplace_back(val);
}
val = 0;
i += 2;
while (i < int(input.size())) {
val = 10 * val + input[i] - '0';
++i;
}
in.aim = val;
return in;
}
int solution(std::string str1){
const Input in = read(str1);
const std::vector<int>& arr = in.arr;
const int aim = in.aim;
// result = dp[n][aim]
int dp[aim + 1];
for (int i = 0; i <= aim; ++i) {
dp[i] = -1;
}
dp[0] = 0;
for (int i = 0; i < int(arr.size()); ++i) {
const int val = arr[i];
for (int j = val; j <= aim; ++j) {
if (dp[j-val] == -1) {
continue;
} else if (dp[j] == -1) {
dp[j] = dp[j-val] + 1;
} else {
dp[j] = std::min(dp[j], dp[j-val]+1);
}
}
}
return dp[aim];
}
4 小艺照镜子
题目描述
已知字符串str。 输出字符串str中最长回文串的长度。
思路
枚举每个位置,向两边扩张,看是不是回文串。
代码
int solution(std::string s){
int result = 1;
for (int i = 0; i < int(s.length()); ++i) {
// 假设串的长度为奇数
int left = i - 1;
int right = i+1;
while (left >= 0 && right < int(s.length()) && s[left] == s[right]) {
--left;
++right;
}
result = std::max(result, right - left - 1);
// 假设串的长度为偶数
left = i;
right = i+1;
while (left >= 0 && right < int(s.length()) && s[left] == s[right]) {
--left;
++right;
}
result = std::max(result, right - left - 1);
}
return result;
}