Codeforces Goodbye 2018 上分记
2018最后一场cf了,how time fies!
作为一个中学生,有时间能参加的cf比赛实在是少之又少,以至于我现在才打了3场现场比赛,其他的都是virtual participation。
终于把C题做出来辣!终于涨rating辣!
下面把我会的题目都打上来:
A题
woc这是英语阅读题啊!
题面那么长,说到底就是求一个最大的\(n+(n+1)+(n+2)\)和。
显然分三种情况,一一枚举即可。
代码:
#include<iostream>
int main()
{
int y, b, r; std::cin >> y >> b >> r;
if(y + 1 <= b && y + 2 <= r)
{
std::cout << y + y + 1 + y + 2 << std::endl;
}
else if(b - 1 <= y && b + 1 <= r)
{
std::cout << 3 * b << std::endl;
}
else if(r - 2 <= y && r - 1 <= b)
{
std::cout << r + r - 1 + r - 2 << std::endl;
}
return 0;
}
B题
同样是一道英语阅读题啊!
大意就是:给你\(n\)个点,然后有\(n\)个提示,提示与上面给的点一一对应,但不知道具体对应关系,求目标点坐标。
我差点不会做
看到\(n\)只有\(1000\),大胆使用暴力算法:把所有可能指示的坐标都弄出来,最终重合了\(n\)次的那个点就是目标点了。
但是坐标范围是\([-3 \times 10^6,3 \times 10^6]\),没办法开这样的数组啊!
仔细想一想,只需要hash一下就完事了。开龙龙显然存得下。
最后用最暴力的std::map
过掉system test。
代码:
#include<iostream>
#include<map>
using namespace std;
#define ll long long
const int maxn = 1005;
struct Nodes
{
int x, y;
} s[maxn];
int n;
map<ll,int> mmp;
ll id(int x, int y)
{
return (x - 3000000) * 3000000 + y - 3000000;
}
int main()
{
cin >> n;
for(int i = 1; i <= n; i++)
{
cin >> s[i].x >> s[i].y;
}
for(int i = 1; i <= n; i++)
{
int xx, yy; cin >> xx >> yy;
for(int j = 1; j <= n; j++)
{
int newx = s[j].x + xx, newy = s[j].y + yy;
//std::cout << newx << ' ' << newy << endl;
mmp[id(newx, newy)]++;
if(mmp[id(newx, newy)] == n)
{
std::cout << newx << ' ' << newy << endl;
return 0;
}
}
}
return 0;
}
C题
终于不是阅读题了。但是题目就变难了。
看到\(n \leq 10^9\),就知道要凉辣 不是轻轻松松就想出来的。
想不出来打暴力看规律,这道题暴力能解决的\(n\)还能到几十万。
暴力看规律(看了好久的规律)可以发现一些最基本的性质:
- 当\(n\)是质数时,答案只有1和\(n\)的某个倍数。
- \(k\)的前半部分与后半部分是对称的。
- 当长度相同时,对应的答案也相同。并且,长度相同中,\(k\)最小的那个方案,所有的数都是递增的。
接下来通过上个厕所等奇技淫巧可以发现解题的关键结论:**方案的长度与\(k\)有关,关系是\(gcd(n,k) \times len = n\) **
所以我们通过枚举\(n\)的所有因数,可以得到所有的最小\(k\),然后可以发现要求的和就是等比数列呀!所以开个龙龙套个公式就可以求出和。
我们这样的枚举是不会有重复的,所以复杂度是优美的\(O(\sqrt{n})\)。
代码:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
vector<ll> vec;
ll n;
ll getsum(ll a1, ll d, ll n)
{
return n * a1 + n * (n - 1) / 2 * d;
}
int main()
{
cin >> n;
for(ll i = 1; i * i <= n; i++)
{
if(n % i == 0)
{
ll temp = n / i;
// solve i
//cout << getsum(1, temp, i) << endl;
vec.push_back(getsum(1, temp, i));
if(i != temp)
{
// solve temp
//cout << getsum(1, i, temp) << endl;
vec.push_back(getsum(1, i, temp));
}
}
}
sort(vec.begin(), vec.end());
for(auto it = vec.begin(); it != vec.end(); ++it)
{
cout << *it << ' ';
}
cout << endl;
return 0;
}
D题
其实我不会,看到dp我就溜了。那个时候好像已经12点了。
但是我要留坑!
希望我不会咕咕
事后
怀着涨rating的希望醒来,发现自己真的涨rating辣!
涨到1424,离超越最开始的1484还差一场比赛!回归青名!(虽然青名也不厉害)
无事的事后看到tourist,又涨rating了?!3559!破天荒的高!
tourist一分钟内切掉了A题!
最近的一场Hello 2019是没办法打了。我不知道还能不能碰到一场div.3来上分了。
不管了,反正ADD OIL就完事辣!