CSDN竞赛第50期个人题解(C++)

个人简介

在读大二,区域赛打铁。

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值