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就完事辣!