Codeforces Round 812 (Div. 2)

发布时间 2023-12-13 16:54:41作者: 加固文明幻景

基本情况

第一次赛时做出div2的ABC。

然而B题是秒的最快的?

A题卡了一段时间经典+4,C题代码实现卡了一段时间。

A. Traveling Salesman Problem

Problem - A - Codeforces

卡题分析

主要原因在少了特判,没有自己多构造几个特殊情况数据。

这是一开始的代码

void solve()
{
	int n, x, y;
	int max_x, max_y, min_x, min_y;
	max_x = max_y = -0x7fffffff, min_x = min_y = 0x7fffffff;
	std::cin >> n;
	while(n--)
	{
		std::cin >> x >> y;
		max_y = std::max(max_y, y), min_y = std::min(min_y, y);
		max_x = std::max(max_x, x), min_x = std::min(min_x, x);
	}
	std::cout << (max_x - min_x + max_y - min_y << 1) << std::endl;
}

这忽略了一些数据,比如说我造的一个:

4
0 -2
0 -3
1 0
-1 0

这类在 \(x\)\(y\) 轴的其中一个或几个方向没有任何箱子的数据在我的做法下就是有问题的,因为此时没法计算从原点到有箱子的那个方向的距离,只是单纯计算了那个方向箱子距离的差值

加入特判即可

void solve()
{
	int n, x, y;
	int max_x, max_y, min_x, min_y;
	max_x = max_y = -0x7fffffff, min_x = min_y = 0x7fffffff;
	std::cin >> n;
	while(n--)
	{
		std::cin >> x >> y;
		max_y = std::max(max_y, y), min_y = std::min(min_y, y);
		max_x = std::max(max_x, x), min_x = std::min(min_x, x);
	}
    int res = max_x - min_x + max_y - min_y;
    if (max_x < 0) res -= max_x;//最大的都小于零,显然都在下方
    if (max_y < 0) res -= max_y;
    if (min_x > 0) res += min_x;//最小的都大于零,显然都在上方
    if (min_y > 0) res += min_y;
	std::cout << (res << 1) << std::endl;
}

B. Optimal Reduction

Problem - B - Codeforces

思想和这类题是一样的:

注意到我们可以把数组变成柱状图并“切片”,有几片答案就是几,而片数很好统计:每当数组元素增加时都会产生一个或几个“切片”的左端,增加几就是几个“切片”。

C. Build Permutation

Problem - C - Codeforces

卡题分析

二分加(贪心?)过了。

这题我得到经验,就是如果代码一大坨了,就尽量先简化、重写,这样比较容易调好。

附上代码(psq是预处理的完全平方数,从零开始)

void solve()
{
	int n;
	std::cin >> n;
	memset(vis, false, sizeof(vis));
	auto now = std::upper_bound(psq.begin(), psq.end(), n - 1);
	for (int i = n - 1; i >= 0; i--)
	{
		if (*now >= i) 
		{
			while(*now - i >= n && now != psq.begin()) now--;
			while(vis[*now - i] && now != psq.begin()) now--;
			ans[i + 1] = *now - i, vis[*now - i] = true;
		}
		else
		{
			now = std::upper_bound(psq.begin(), psq.end(), n - 1);
			while(vis[*now - i] && now != psq.begin()) now--;
			ans[i + 1] = *now - i, vis[*now - i] = true;
		}
	}
	for (int i = 1; i <= n; i++) std::cout << ans[i] << " ";
	std::cout << std::endl;
}