塔子月赛第一场——一坤题坐牢场

文章介绍了CodeFun2000编程比赛中的一系列问题,包括一道涉及中位数和数组处理的模拟题,一个需要使用线段树的动态区间维护问题,一个找规律的数论题,以及一个未解的难题。作者分享了他们的解题思路和部分代码实现,特别提到第三题的规律推理过程。
摘要由CSDN通过智能技术生成

首先非常感谢塔子举办这一场比赛,本菜排位rk9,差点白忙活(滑稽

网址如下:Home - CodeFun2000

还是那句话,懂的人,一眼div4A;不懂的人,怎么看都是div1F(泪目

就本场四题,本菜简单汪两声:


T1 苦逼打工塔 Problem Detail - 塔子月赛1-第一题-苦逼打工塔 - CodeFun2000        

        具体题干这里就不放了。

        这是一道,emmm,很恶心(不知道合不合适)的小模拟题,首先需要考虑对所有的-1进行去除,以求取中位数;然后需要对每一个数进行处理和赋值,对-1的数进行统计计数;最后从第一个非-1的位置开始输出。如下:

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using pll = pair<ll, ll>;
void solve()
{
	int n, k;
	cin >> n >> k;
	vector<ll>you;
	vector<ll>tot;
	for (int i = 0; i < n; i++)
	{
		int x;
		cin >> x;
		if (x != -1)
			you.push_back(x);
		tot.push_back(x);
	}
	bool flg = false;
	sort(you.begin(), you.end());
	ll mod = you[(int)you.size() / 2];
	vector<int>ans(n);
	for (int i = 0; i < n; i++)
	{
		if (tot[i] == -1)
		{
			int cnt = 0;
			int j = i;
			while (j < n && tot[j] == -1)
			{
				++cnt;
				++j;
			}
			if (cnt > 3 || i == 0)
			{
				for (int t = i; t < j; t++)
					ans[t] = -1;
			}
			else
			{
				for (int t = i; t < j; t++)
					ans[t] = ans[i - 1];
			}
			i = j - 1;
		}
		else if ((ll)abs(tot[i] - mod) <= k)
			ans[i] = 1;
		else if (tot[i] - k > mod)
			ans[i] = 2;
		else
			ans[i] = 0;
	}
	int j = 0;
	while (ans[j] == -1)
		j++;
	for (int i = j; i < n; i++)
		cout << ans[i] << ' ';
	cout << endl;
}
int main()
{
	int t = 1;
	//cin >> t;
	while (t--)
	{
		solve();
	}
	return 0;
}

T2 2333的超级队列 Problem Detail - 塔子月赛1-第二题-2333的超级队列 - CodeFun2000

        由于做的比较急,而且意识到这题不用一些稍微复杂的手段搞不定,于是选择暴力骗分。实际上这题需要使用线段树进行区间维护和动态修改。本菜还没来得及补题,届时将会更新本文。

        膜2333佬orz


T3 2333的小清新数论题 Problem Detail - 塔子月赛1-第三题-2333的小清新数论题 - CodeFun2000

        一道很折磨的找规律题,那么,开始推理,我们可以暴力的计算出前8种排列组合的方式,当然一定要朝着一个方向,样例在多解上给出了一定的坑,要是一味的考虑多解,那注定会经历一段难以忍受的坐牢时光。

        很显然,读懂题目之后可以发现,构造的数组的和的最大值一定是 n*(n+1)/2,而且,相邻两个前缀和的gcd就是构造出来的数组的那个位置的数。比如 n=5,数组 5 1 2 4 3,前缀和 5 6 8 12 15,观察到除了第一个数,前缀和数组中那个位置 i 的数和前一个位置 i-1 的数的gcd就是原数组中的那个位置 i 的数。

        对于n为偶数,下一个从2开始;n为基数,则下一个从1开始,那么n+1又是偶数,又可以从2开始,好了,这是一个很好的起点。至于为什么这样可以,那也许就是规律罢(心虚

        举个例子,n=8,那么按照我们上面的推理,8后面是2,于是有 8 2,当前前缀和为10,再往后,需要找一个没有出现过的数 x,使得 10+x 与 10 的gcd结果为 x,那么显然 x必然是 10 的一个因子,2取过了,于是取5,至于为什么不取 1 和 10,因为推出来是错的(呜呜)。

        那么当前数组为 8 2 5,前缀和 15,再往后,取 3......

        我们可以推出 n=8 时,构造的数组为 8 2 5 3 6 4 7 1。

        再玩个小的,n=6 时,构造的数组为 6 2 4 3 5 1。

        那么偶数就搞定了,n之后两两成对,和的起点为 n/2+3,以公差为2递增,至于这个怎么这么快就出来了,那只能说,规律嘛,是这样的。

        然后考虑奇数,相似的,将 1 移到 n 的后面,以 n=5 为例,5 1 的和为6,仿照上面偶数情况,那么构造的数组就是 5 1 2 4 3。

        再玩个大的,n=7 时,构造的数组为 7 1 2 5 3 6 4,最后一个数总是 (n+1)/2。

那么这题就结束了,如下:

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using pll = pair<ll, ll>;
vector<vector<int>>grid;
void solve()
{
	ll n;
	cin >> n;
	if (n == 1)
		cout << "1" << endl;
	else if (n == 2)
		cout << "2 1" << endl;
	else if (n == 3)
		cout << "3 1 2" << endl;
	else if (n == 4)
		cout << "4 2 3 1" << endl;
	else if (n == 5)
		cout << "5 1 2 4 3" << endl;
	else if (n == 6)
		cout << "6 2 4 3 5 1" << endl;
	else if (n == 7)
		cout << "7 1 2 5 3 6 4" << endl;
	else if (n == 8)
		cout << "8 2 5 3 6 4 7 1" << endl;
	// 9 1 2 6 3 7 4 8 5
	// 10 2 6 3 7 4 8 5 9 1
	else
	{
		if (n % 2 == 0)
		{
			cout << n << " ";
			int mod = n / 2 + 3;
			for (int i = 2; i < (n / 2); i++)
			{
				cout << i << " " << mod - i << " ";
				mod += 2;
			}
			cout << n / 2 << " " << n - 1 << " " << 1 << endl;
		}
		else
		{
			int mod = (n + 1) / 2 + 3;
			cout << n << " " << 1 << " ";
			for (int i = 2; i < (n + 1) / 2; i++)
			{
				cout << i << " " << mod - i << " ";
				mod += 2;
			}
			cout << (n + 1) / 2 << endl;
		}
	}
}
int main()
{
	int t = 1;
	//cin >> t;
	while (t--)
	{
		solve();
	}
	return 0;
}

T4 塔子的数数题 Problem Detail - 塔子月赛1-第四题-塔子的数数题 - CodeFun2000

        本菜真看不懂这题,有些晕头转向,等补题的时候再看看题解罢


总结:

        这一场的题目都难的恰到好处,就是本菜只做了一坤题,有些可惜,T3害人不浅(doge

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值