【CSDN竞赛第33期】C++题解

19 篇文章 2 订阅
4 篇文章 0 订阅

奇偶排序

给定一个存放整数的数组,重新排列数组使得数组左边为奇数,右边为偶数。(奇数和偶数的顺序根据输入的数字顺序排列)

算法

开两个vector,按照要求读入数据,如果当前数据为奇数,则加到第一个vector中,否则加入第二个vector中。

参考代码(C++)

#include <bits/stdc++.h>
using namespace std;
int n;
vector<int> a, b;
int main() {
	cin >> n;
	while(n --) {
		int x;
		cin >> x;
		if(x % 2 == 0) b.push_back(x);
		else a.push_back(x);
	}
	for(int x : a) cout << x << " ";
	for(int x : b) cout << x << " ";
	return 0;
}

小艺改编字符串

已知字符串str. 添加至少多少字符可以使得str变成回文串。

算法

求出字符串中的最长回文子序列即可,可以求解原串s和原串的反转t的最长公共子序列,那么这个最长的子序列就是最长回文子序列。

参考代码(C++)

#include <bits/stdc++.h>
using namespace std;
int n;
int main() {
	string s;
	cin >> s;
	string t;
	for(char c : s) t.push_back(c);
	reverse(t.begin(), t.end());
	n = s.size() + 1;
	vector<vector<int>> f(n + 1, vector<int>(n + 1));
	for(int i = 0; i < n; i ++)
	for(int j = 0; j < n; j ++) {
		if(s[i] == t[j]) f[i + 1][j + 1] = f[i][j] + 1;
		else {
			f[i + 1][j + 1] = max(f[i][j + 1], f[i + 1][j]);
		}
	}
	cout << n - f[n][n] << "\n";
	return 0;
}

公司新表

公司里为了凸显公司的特性。 安装了一个n进制表。 已知新的表的时间是”H:M”。 时间合法的定义为H<=23 &&M<=59。 时间有多少种进制定义的方式,依次打印出来。 如果有无数种解输出”-1”,不存在输出”0”。

算法

进制转换题,考虑清楚哪些情况下是无数组解的就可以了。

参考代码(C++)

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int main() {
	string s;
	cin >> s;
	bool flag = false;
	s = " " + s;
	int mid, b = 2;
	for(int i = 1; i < s.size(); i ++) {
		if(s[i] == ':') mid = i;
		else if(s[i] >= 'A') b = max(b, s[i] - 'A' + 11);
		else b = max(b, s[i] - '0' + 1);
	}
	for(int i = b; i; i ++) {
		int base = 1, x = 0, y = 0;
		for(int j = mid - 1; j >= 1; j --) {
			if(s[j] >= '0' && s[j] <= '9') x += base * (s[j] - '0');
			else x += base * (s[j] - 'A' + 10);
			base *= i;
		}
		base = 1;
		for(int j = s.size() - 1; j > mid; j --) {
			if(s[j] >= '0' && s[j] <= '9') y += base * (s[j] - '0');
			else y += base * (s[j] - 'A' + 10);
			base *= i;
		}
		if(x < b && y < b && x <= 23 && y <= 59) {
			cout << -1 << "\n";
			return 0;
		}
		if(x > 23 || y > 59) break;
		flag = true;
		cout << i << " ";
	}
		
	if(!flag) cout << 0 << "\n";
	return 0;
}

选择客栈

丽江河边有 n 家很有特色的客栈,客栈按照其位置顺序从 1 到 n 编号。每家客栈都按照某一种色调进行装饰(总共 k种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均有各自的最低消费。 两位游客一起去丽江旅游,他们喜欢相同的色调,又想尝试两个不同的客栈,因此决定分别住在色调相同的两家客栈中。晚上,他们打算选择一家咖啡店喝咖啡,要求咖啡店位于两人住的两家客栈之间(包括他们住的客栈),且咖啡店的最低消费不超过 p 。 他们想知道总共有多少种选择住宿的方案,保证晚上可以找到一家最低消费不超过 p 元的咖啡店小聚。

算法

贪心,假设当前客栈的的颜色为c,最低消费为d,如果d不大于题意中的最低消费p,那我们 记下当前位置idx(颜色为c的位置),接下来判断,如果idx不小于上一个颜色为c的位置,那么当前颜色的客栈我们可选的有之前出现颜色为c的客栈总数,接着答案加上当前颜色的可选数量(具体构造方案:咖啡店选择最后一个满足最低消费不大于p的,客栈也固定选择和咖啡相同的一家,另外一个客栈在相同的颜色的可选客栈中任选一个即可)。

参考代码(C++)

#include <bits/stdc++.h>
using namespace std;
int main() {
	int n, k, p;
	cin >> n >> k >> p;
	vector<int> last(k), sum(k), cnt(k);
	int idx = -1, ans = 0;
	int col, least;
	for(int i = 0; i < n; i ++) {
		cin >> col >> least;
		if(least <= p) idx = i;
		if(idx >= last[col]) sum[col] = cnt[col];
		ans += sum[col];
		last[col] = i;
		cnt[col] ++ ;
	}
	cout << ans << "\n";
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值