Codeforces Round #679 (Div.2)
這場解出了 pABCD 不過速度有點慢
如果速度在快一點 應該能上更多分
不過這場把我前一天摔青的分數全都加回來了
已經算是不錯了


Problem A - Finding Sasuke

這題的關鍵在 is even 的這句話
很明顯我們就可以讓 來讓總和為
程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #include <bits/stdc++.h> #define int long long #define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); using namespace std; void solve(){ int n; cin >> n; int arr[n]; for(auto &x : arr) cin >> x; for(int i = 0;i < n;i+=2){ cout << -arr[i+1] << " " << arr[i] << " "; } cout << "\n"; } signed main(){ fastio int t = 1; cin >> t; while(t--) solve(); }
|
Problem B - A New Technique

給任意順序的直行以及橫列
問你是否能找出原來的版面
我原本以為數字會重複 用了很麻煩的解
但是他提到 “It is also guaranteed that each number from to occurs exactly once”
就判斷一行就好
程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| #include <bits/stdc++.h> #define int long long #define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); using namespace std; void solve(){ int n,m; cin >> n >> m; map<int,int> idx; int arr[n][m]; for(int i = 0;i < n;i++) for(int j = 0;j < m;j++){ cin >> arr[i][j]; if(j==0) idx[arr[i][j]] = i+1; } vector<int> a(n); for(int i = 0;i < m;i++){ vector<int> order(n); bool ok = 1; for(int j = 0, tmp;j < n;j++){ cin >> tmp; order[j] = idx[tmp]; if(idx[tmp]==0) ok = 0; } if(ok) a = order; } for(int i = 0;i < n;i++){ for(int j = 0;j < m;j++) cout << arr[a[i]-1][j] << " "; cout << "\n"; } } signed main(){ fastio int t = 1; cin >> t; while(t--) solve(); }
|

這題基本上可以把題目化成 Smallest Range in K List
然後用他的概念就可以解出來了
(賽中想不到解法就直接抄code下來了)
程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| #include <bits/stdc++.h> using namespace std; void smallestRange(vector<vector<int>>& nums) { int rangeLeft = 0, rangeRight = INT_MAX; int size = nums.size(); vector<int> next(size); auto cmp = [&](const int& u, const int& v) { return nums[u][next[u]] > nums[v][next[v]]; }; priority_queue<int, vector<int>, decltype(cmp)> pq(cmp); int minValue = 0, maxValue = INT_MIN; for (int i = 0; i < size; ++i) { pq.emplace(i); maxValue = max(maxValue, nums[i][0]); } while (true) { int row = pq.top(); pq.pop(); minValue = nums[row][next[row]]; if (maxValue - minValue < rangeRight - rangeLeft) { rangeLeft = minValue; rangeRight = maxValue; } if (next[row] == nums[row].size() - 1) { break; } ++next[row]; maxValue = max(maxValue, nums[row][next[row]]); pq.emplace(row); } cout << rangeRight-rangeLeft << "\n"; }
int main() { int a[6]; for(auto &x : a) cin >> x; sort(a,a+6,greater<int>()); int n; cin >> n; vector<vector<int>> arr(n,vector<int>(6)); for(int i = 0, tmp;i < n;i++){ cin >> tmp; for(int j = 0;j < 6;j++){ arr[i][j] = tmp-a[j]; } } smallestRange(arr); return 0; }
|
Problem D - Shurikens

看到這題的時候讓我想到 dsu 的拔邊與加邊的題目
可以將詢問與操作反轉過來進行
這個題目就變得很簡單了
用一個 set 維護所有的元素
當出現比最小元素還大的元素 或 要拿掉 set 的元素但 set 是空的
都可以直接回答 NO
最後的程式碼就很簡單了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| #include <bits/stdc++.h> #define int long long #define fastio ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); using namespace std; signed main(){ fastio int n; cin >> n; n*=2; set<int> s; vector<int> ans; vector<pair<char,int>> v; while(n--){ char c; int val = 0; cin >> c; if(c=='-'){ cin >> val; } v.push_back({c,val}); } while(!v.empty()){ auto [c,val] = v.back(); v.pop_back(); if(c=='+'){ if(s.empty()){ cout << "NO\n"; return 0; } ans.push_back(*s.begin()); s.erase(*s.begin()); }else{ if(!s.empty()&&val > *s.begin()){ cout << "NO\n"; return 0; }else{ s.insert(val); } } } cout << "YES\n"; reverse(ans.begin(),ans.end()); for(auto x : ans) cout << x << " "; }
|