5/16 【汉中校区周赛题解】

~ 2026-5-23 16:16:10

A. 等差数列变化求和

分析

  • 难度:比较麻烦的数学题。
  • 子任务 1(30 分)min(r, max(l, a1))
  • 子任务 2(30 分):直接暴力枚举即可。
  • 子任务 3(40 分):显然麻烦的点是情况非常多,可能递增或递减,可能分为三段、两段或一段,中间的情况也会非常复杂。 大家要学会不要只一味的判断当前情况,而要提前预处理做一些整理才能让后续事半功倍。我的代码第一步就是先把递减的序列转换为对应等价的递增序列。这样情况就简单了非常多。 然后把三段直接用数学方法算出分界点,分别用对应的规则进行计算即可。

满分参考代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, a1, d, l, r;
signed main()
{
	freopen("sum.in", "r", stdin);
	freopen("sum.out", "w", stdout);
	cin >> n >> a1 >> d >> l >> r;

	// 调整数列,为连续上升
	if (d < 0)
	{
		a1 = a1 + (n - 1) * d;
		d = -d;
	}

	int ans = 0;

	// lllll
	if (a1 < l)
	{
		// 前 cnt 项都 <= l,第 cnt+1 项肯定大于 l
		int cnt = (l - a1) / d + 1;
		if (cnt > n)
			cnt = n;
		ans += cnt * l; // cnt 个 l
		a1 += cnt * d;	// 首项变到第 cnt+1 项
		n -= cnt;		// 现在少了 cnt 项
	}
	// 等差阶段
	if (a1 < r)
	{
		// 前 cnt 项都 <= r,第 cnt+1 项肯定大于 r
		int cnt = (r - a1) / d + 1;
		if (cnt > n)
			cnt = n;
		// 首项 加 末项 乘以 项数 除以 2
		ans += (a1 + (a1 + (cnt - 1) * d)) * cnt / 2;
		a1 += cnt * d;
		n -= cnt;
	}

	// rrrrrr 后面的全都大于 r
	ans += n * r;

	cout << ans;
	return 0;
}

B. 停车费计算

分析

  • 难度:基础的求和,求和的每一项都根据具体情况计算价格即可。
  • 子任务 1(30 分):每天只有两种费用,00aa 元,判断每天停车时间是否大于 xx 来决定加多少即可。
  • 子任务 2(30 分):第一个小时和后续价格一致,超过 xx 元直接算出多少个小时乘以对应的单价即可。
  • 子任务 3(40 分):每天的停车时长算出属于哪一档,按规则计算即可。

满分参考代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
int n;		 // 总次数
int x;		 // 免费时长
int y, a, b; // 第一个 y 分钟 a 元。后面每 y 分钟 b 元
int t[10005], ans;
signed main()
{
	freopen("park.in", "r", stdin);
	freopen("park.out", "w", stdout);
	cin >> n;
	cin >> x;
	cin >> y >> a >> b;
	for (int i = 1; i <= n; i++)
		cin >> t[i];

	ans = 0;
	for (int i = 1; i <= n; i++)
	{
		if (t[i] <= x)
			continue;
		if (t[i] <= y)
		{
			ans += a;
			continue;
		}
		int cnt = (t[i] + (y - 1)) / y;
		ans += a + (cnt - 1) * b;
	}
	cout << ans;
	return 0;
}

C. 复制画作

分析

  • 难度:基础绘图,注意转义符。

满分参考代码

#include <bits/stdc++.h>
using namespace std;
string g[4] = {"./\\.", "/..\\", "\\../", ".\\/."};
int main()
{
	freopen("copy.in", "r", stdin);
	freopen("copy.out", "w", stdout);
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
		for (int row = 0; row <= 3; row++)
		{
			for (int j = 1; j <= m; j++)
			{
				cout << g[row];
			}
			cout << "\n";
		}
	return 0;
}

D. 计算补码

分析

  • 难度:按照补码规则处理即可,最后的加 11 稍微麻烦一点。按竖式计算即可。

满分参考代码

#include <bits/stdc++.h>
using namespace std;
string s;
int main()
{
	freopen("code.in", "r", stdin);
	freopen("code.out", "w", stdout);
	cin >> s;
	if (s[0] == '0')
	{
		cout << s;
		return 0;
	}
	for (int i = 1; i <= (int)s.size() - 1; i++)
	{
		if (s[i] == '0')
			s[i] = '1';
		else
			s[i] = '0';
	}
	int add = 1; // 进位
	for (int i = (int)s.size() - 1; i >= 0; i--)
	{
		int num = s[i] - '0' + add;
		add = num / 2;
		num = num % 2;
		s[i] = '0' + num;
	}
	cout << s;
	return 0;
}


我们会审查剪贴板内容,并对发布不合适内容的同学进行相应的处理