第八届传智杯程序设计初赛A组 部分题解

「C++ 40 周年」主题征文大赛(有机会与C++之父现场交流!) 10w+人浏览 457人参与

目录

1,小红的大小写字母

2,锁

3,牛牛的括号式

4,题目忘了

5,赛后AI所解


1,小红的大小写字母

大概题意是小红拿到了一个由大小写字母构成的长度为 N 的字符串,他每次操作可以将一个字符在大小写之间交换。

小红希望恰好 K 次操作后,大写字母的数量尽可能的多。

求最终字符串中大写字符的数量。

1 ≤ N ≤ 10^5, 1 ≤ K ≤ 10^9

输入示例:

1 3
A

输出结果:

0

输入示例:

5 3
arBrg

输出结果:

4

C++题解代码:

#include <bits/stdc++.h>
using namespace std;
#define endl '\\n'
#define int long long
void solve() {
	int n, k;
	cin >> n >> k;
	string s;
	cin >> s;
	int res = 0;
	// num1,num2分别表示字符串中小写字母,大写字母的数量
	int num1 = 0, num2 = 0;	
	for (int i = 0; i < s.size(); i++) {
		char c = s[i];
		if (c >= 'a' && c <= 'z') {
			num1++;
		} 
		if (c >= 'A' && c <= 'Z') {
			num2++;
		}
	}
	// 如果小写字母小于操作次数,则把k个小写字母转化成大写字母
	if (num1 >= k) {	
		res += k + num2;
	} else {	// num1 < k 反之,先把所有的小写字母转化成大写字母
		res += n;
		k -= num1; // 剩下操作次数:k - num1
		// 把剩下操作,对一个字符单独操作,如果(k - num1)为偶数,操作后仍为大写的
		// 否则变为小写,最终结果 - 1
		if (k % 2 != 0) {	
			res--;
		}
	}
	cout << res << endl;
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int _ = 1;
	//cin >> _;
	while (_--) {
		solve();
	}
	return 0;
}

2,锁

大概题意是牛牛有 n 份资源,初始化均处于未上锁状态。

现有 m 次操作,每次给定一个编号 p:

若编号为 p 的资源未上锁,则为其上锁。

否则,解锁;

每次操作后,牛牛希望分别统计区间 [ 1 , x ][ y , n ] 中可以*访问的资源(未上锁的资源)*的数量。

首先有多组测试数据,第一行输入 T ( 1 ≤ T ≤ 10^3 )代表数据组数。

每组测试数据有:

第一行四个整数,分别为 n , m , x , y ;

( 1 ≤ n ≤ 2 x 10^5 )( 1 ≤ m ≤ 4 x 10^5 )( 1 ≤ x ≤ n )( 1 ≤ y ≤ n )

输入示例:

2
4 3 2 3
2
3
3
6 6 4 2
1
3
6
4
4
2

输出结果:

1 2
1 1
1 2
3 5
2 4
2 3
1 2
2 3
1 2

C++代码题解:

#include <bits/stdc++.h>
using namespace std;
#define endl '\\n'
#define int long long
void solve() {
	int n, m, x, y;
	cin >> n >> m >> x >> y;
	map<int, int> p;
	// res1,res2分别表示[1,x],[y,n]区间可以访问的资源数
	int res1 = x , res2 = n - y + 1;	// 初始化(均可访问)
	for (int i = 0; i < m; i++) {
		int t;
		cin >> t;
		p[t]++;			// 标记1: 不可访问(被上锁了) ; 标记0:可访问
		if (p[t] == 2) p[t] = 0;	// 有两次对同一数据操作,标记归零
		if (t >= 1 && t <= x) {
			if (p[t] == 1)	// 标记为 1 编号为 t 的资源被上锁了
				res1--;
			else 			// 反之,编号为 t 的资源又被解锁了
				res1++;
		}
		if (t >= y && t <= n) {	
			if (p[t] == 1)	// 同上
				res2--;
			else
				res2++;
		}
		cout << res1 << ' ' << res2 << endl;
	}
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int _ = 1;	// 有多组测试数据
	cin >> _;
	while (_--) {
		solve();
	}
	return 0;
}

3,牛牛的括号式

大概题意是牛牛给出了一个关于未知量 x 的多项式。这个多项式以字符串的形式表示,它是由若干个形如 ( x - d )( x + d ) 的括号表达式相乘构成。其中 d 是一个1到9的数字字符。

牛牛想知道,这个多项式完全展开后,x 的一次项的系数是多少。

结果可能过大,对结果取模(10007)。

输入示例:

(x+1)(x+2)

输出结果:

3

C++代码题解:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 10007;
int a[100010];	// 存 -d 或 +d 的值,按顺序存
void solve() {
	string s;
	cin >> s;
	// 特殊示例(只有一个式子)如 (x+1)
	if (s.size() == 5) {
		cout << 1 << endl;
		return;
	}
	int len = 1;
	// 取 -d 或 +d 的值
	for (int i = 0; i < s.size(); i += 5) {
		a[len] = s[i + 3] - '0';
		if(s[i + 2] == '-') {
			a[len] *= -1;
		}
		len++;
	}
	// 预处理
	for (int i = 1; i < len; i++) {
	    a[i] = (a[i] % mod + mod) % mod; // 处理负数,确保结果非负
	}
	// 以下是使用递推方式,求 X^1 的系数,其实还可以推导多项式系数公式
	int t1 = (a[1] + a[2]) % mod, t2 = (a[1] * a[2]) % mod;
	for (int i = 3; i < len; i++) {
	    t1 = ((t1 * a[i]) % mod + t2) % mod;
	    t2 = (t2 * a[i]) % mod;
	}
	cout << t1 % mod << endl; 
	
// 多项式 (x + a₁)(x + a₂)...(x + aₙ) 展开后,x^(n-1) 项的系数就是这个总和(初等对称多项式的第 n-1 项)。
// 超时,可以通过逆元优化
//	int sum = 0;
//	for (int i = 1; i < len; i++) {
//		int res = 1;
//		for (int j = 1; j < len; j++) {
//			if (j != i) res = res * a[j] % mod;
//		}
//		sum += res % mod;
//	}
//	cout << sum % mod << endl;
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int _ = 1;
	// cin >> _;
	while (_--) {
		solve();
	}
	return 0;
}

4,题目忘了

区间查询问题:预处理数据后,对每个查询x,返回满足a≤x的最大b值。使用排序优化查询效率。

C++代码题解:

#include <bits/stdc++.h>
using namespace std;
#define endl '\\n'
#define int long long
pair<int, int> p[100010];
void solve() {
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		int a, b;
		cin >> a >> b;
		p[i].first = b;
		p[i].second = a;
	}
	sort(p, p + n);
	int q;
	cin >> q;
	while (q--) {
		int x;
		cin >> x;	// a <= x 
		bool f = false;
		for (int i = n - 1; i >= 0; i--) {
			if (p[i].second <= x) {
				cout << p[i].first << endl;
				f = true;
				break;
			}
		}
		if (!f) cout << -1 << endl;
	}
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0); 
	int _ = 1;
	// cin >> _;
	while (_--) {
		solve();
	}
	return 0;
}

5,赛后AI所解

字符串子串统计问题:计算不含"d"且至少包含一个"e"和一个"r"的子串数量。采用容斥原理分块处理字符串。

是否正确不确定

AI代码:

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
void solve() {
	string s;
	cin >> s;
	int res = 0;
	int n = s.size();
	int start = 0;
	
	// 按'd'分割字符串,处理每个不含'd'的子段
	while (start < n) {
		// 跳过所有'd',找到子段起始
		while (start < n && s[start] == 'd') start++;
		if (start >= n) break;
		
		// 找到当前子段的结束位置(下一个'd'或字符串末尾)
		int end = start;
		while (end < n && s[end] != 'd') end++;
		
		// 提取当前子段(也可直接遍历,避免substr开销)
		int m = end - start;
		int total = m * (m + 1) / 2; // 该子段总子串数
		
		// 计算不含'e'的子串数
		int no_e = 0, cnt = 0;
		for (int i = start; i < end; i++) {
			if (s[i] != 'e') cnt++;
			else {
				no_e += cnt * (cnt + 1) / 2;
				cnt = 0;
			}
		}
		no_e += cnt * (cnt + 1) / 2;
		
		// 计算不含'r'的子串数
		int no_r = 0; cnt = 0;
		for (int i = start; i < end; i++) {
			if (s[i] != 'r') cnt++;
			else {
				no_r += cnt * (cnt + 1) / 2;
				cnt = 0;
			}
		}
		no_r += cnt * (cnt + 1) / 2;
		
		// 计算既不含'e'也不含'r'的子串数
		int no_e_r = 0; cnt = 0;
		for (int i = start; i < end; i++) {
			if (s[i] != 'e' && s[i] != 'r') cnt++;
			else {
				no_e_r += cnt * (cnt + 1) / 2;
				cnt = 0;
			}
		}
		no_e_r += cnt * (cnt + 1) / 2;
		
		// 容斥原理:有效子串数 = 总 - 不含e - 不含r + 既不含e也不含r
		res += (total - no_e - no_r + no_e_r);
		
		// 移动到下一个子段起始
		start = end;
	}
	
	cout << res << endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0); 
	int _ = 1;
	// cin >> _;
	while (_--) {
		solve();
	}
	return 0;
}

第六届B初赛播客举办的一次IT技术竞赛的初赛阶段,旨在选拔出各高校优秀的程序设计人才。该比赛中,参赛者将面临多道编程题目,通过编写程序解决问题来展示他们的技术水平和创新能力。 在初赛中,参赛者需要在规定的时间内完成多道程序设计题目。这些题目可能涉及数据结构、算法、网络通信等方面的知识,要求参赛者具备扎实的编程基础和解决实际问题的能力。 参赛者需要在规定的时间内完成编程题目,并提交给评委进行评分。评委会根据答案的正确性、效率、代码的可读性等方面对参赛者的作品进行综合评判。最终,得分高的参赛者将进入下一轮比赛。 第六届B初赛的目的是为了选拔出具备优秀编程能力的学生,为他们提供一个展示才华、学习交流的平台。参赛者不仅可以通过比赛锻炼自己的编程技巧,还可以结识其他优秀的参赛者,相互学习、切磋技艺。 在比赛过程中,参赛者还可以通过与其他选手交流,了解各种不同的编程思路和解题方法,不断提高自己的编程水平。同时,参赛者还有机会与业界的专家学者进行交流,了解最新的技术动态和发展趋势。 总之,第六届B初赛是一次很有意义的编程竞赛,为各大高校的IT人才选拔提供了一次难得的机会。通过比赛,参赛者可以展现自己的才华,提升技术水平,同时也可以与其他优秀选手进行交流,共同进步。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值