Codeforce:Good Bye 2020 個人題解
阿新 • • 發佈:2020-12-31
題面連結:Here
程式碼提交:Here
年終彩蛋
1466A. Bovine Dilemma
題意是:給定一個固定點(0,1)
,然後給定n
個在x軸的點,求面積不同的三角形個數
簡單思考一下就容易發現這個是一個高相等的三角形,只需要去比較底邊的長度不同的有多少個即可。
//AC程式碼 void solve() { cin >> n; vector<int> v(n); for (int i = 0; i < n; ++i) cin >> v[i]; if (n == 1) { cout << 0 << endl; return; } set<int> s; for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) if (i != j) s.insert(v[j] - v[i]); //由於直接暴力找的答案是正解的兩倍(會存入等大小的負值),所以要除2 cout << s.size() / 2 << endl; }
進階挑戰:Try to solve it for \(n,x_i≤10^5\).
//待補
1466B. Last minute enhancements
給定\(n\) 個音符的值,當可以為重複出現的值加一時,最終能有多少個不同音符
標記出現過的,如果下次還出現則令其加一再標記
//原提交寫法 void solve() { cin >> n; vector<int> v(n); int cnt = 0, sum = 0; int book[2 * (n + 1)] = {0}; set<int> s; for (int i = 0; i < n; ++i) { cin >> v[i]; if (book[v[i]]) v[i]++; s.insert(v[i]); book[v[i]]++; } if (n == 1) { cout << 1 << endl; return; } cout << s.size() << endl; }
//寫法優化
void solve() {
ll n, x;
cin >> n;
set<ll> s;
for (int i = 0; i < n; ++i) {
cin >> x;
if (s.count(x))
x++;
s.insert(x);
}
cout << s.size() << endl;
}
//多利用STL函式幫助解決問題
進階挑戰:對於給定的 \(k_i\),如果我們可以將音符 \(x_i\) 增加 [0,\(k_i\)
//待補
1466C. Canine poetry
如果存在一個長度大於3的迴文,則存在一個長度為2或3的迴文。此觀察結果使我們可以簡化擦除所有長度為2或3的迴文的任務。 每個字元最多將被替換一次。
從現在開始,有幾種可能的解決方案。 最簡單的方法是從左到右遍歷一個單詞。 當我們遇到以當前位置結束的迴文(長度為2或3),並且由未標記的元素組成時,我們會貪婪地將此字元標記為要替換的字元。 標記字元的數目就是答案,因為事實證明,通過僅替換標記位置上的字母,我們可以獲得有效的無迴文序列。 複雜度為O(n)。
當然這道題也可以用DP做,但更復雜:時間複雜度\(O(n*26^2)\)
char s[N];
bool vis[N];
void solve() {
cin >> (s + 1);
n = strlen(s + 1);
for (int i = 1; i <= n; i += 1)
vis[i] = 0;
int ans = 0;
for (int i = 1; i <= n; i += 1) {
if (i >= 2 and s[i] == s[i - 1] and not vis[i - 1]) {
vis[i] = 1;
ans += 1;
}
if (i >= 3 and s[i] == s[i - 2] and not vis[i - 2] and not vis[i]) {
vis[i] = 1;
ans += 1;
}
}
cout << ans << "\n";
}
進階挑戰:如果字母可以更改,並且每次更改後都需要計算結果怎麼辦?
1466D. 13th Labour of Heracles
樹構造,寫一下入度和出度
ll w[N];
int d[N];
void solve() {
cin >> n;
for (int i = 1; i <= n; i++)
cin >> w[i], d[i] = 0;
for (int i = 1, u, v; i < n; i++) {
cin >> u >> v;
d[u] += 1, d[v] += 1;
}
ll ans = 0;
vector<ll> v;
for (int i = 1; i <= n; i++) {
ans += w[i];
for (int j = 1; j < d[i]; j++)
v.push_back(w[i]);
}
sort(v.begin(), v.end(), greater<ll>());
cout << ans << " ";
for (ll x : v)
cout << (ans += x) << " ";
cout << endl;
}
1466E. Apollo versus Pan
//待補
1466F. Euclid's nightmare
//待補