首先非常感谢塔子举办这一场比赛,本菜排位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