Educational Codeforces Round 149 (Rated for Div. 2)

1|0A. Grasshopper on a Line


#include <bits/stdc++.h> using namespace std; #define int long long void solve(){ int x , k; cin >> x >> k; if( x % k == 0 ){ cout << "2\n" << x - 1 << " " << 1 << "\n"; }else{ cout << "1\n" << x << "\n"; } } int32_t main() { ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); int t; cin >> t; while( t -- ) solve(); return 0; }

2|0B. Comparison String


直接找到连续相同且最长的段即可。

#include <bits/stdc++.h> using namespace std; #define int long long void solve(){ int n; string s; cin >> n >> s; int res = 0 , last = '.', cnt = 0; for( auto i : s ){ if( last == i ) cnt ++; else{ last = i , cnt = 1; } res = max( res , cnt ); } cout << res + 1<< "\n"; return ; } int32_t main() { ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); int t; cin >> t; while( t -- ) solve(); return 0; }

3|0C. Best Binary String


连续的问号和两端的任意一个相同即可。

#include <bits/stdc++.h> using namespace std; #define int long long void solve() { int n; string s; cin >> s; n = s.size(); if( s[0] == '?' ) s[0] = '0'; if( s[n-1] == '?' ) s[n-1] = '1'; for( int i = 1 ; i < n-1 ; i ++ ){ if( s[i] == '?' ){ int j = i; while( s[j] == '?' ) j ++; if( s[i-1] == '1' && s[j] == '1' ) for( int l = i ; l < j ; l ++ ) s[l] = '1'; else for( int l = i ; l < j ; l ++ ) s[l] = '0'; i = j; } } cout << s << "\n"; return; } int32_t main() { ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); int t; cin >> t; while (t--) solve(); return 0; }

4|0D. Bracket Coloring


跑两种括号匹配,然后正序的括号匹配染成一种颜色,反序的括号匹配染成另一种颜色即可。

#include <bits/stdc++.h> using namespace std; #define int long long void solve() { int n; string s; cin >> n >> s; if (n & 1) { cout << "-1\n"; return; } else { int a = 0, b = 0; for (auto i: s) if (i == '(') a++; else b++; if (a != b) { cout << "-1\n"; return; } } n = s.size(); int cnt = 0, st = -1, p = 0; vector<pair<int, int>> res; for (auto i: s) { if (i == '(') { if (st == -1) st = 1, cnt = 1, p = 1; else if (st == 1) cnt++, p++; else if (cnt == 0) { res.emplace_back(st, p); st = 1, cnt = 1, p = 1; } else cnt--, p++; } else { if (st == -1) st = 2, cnt = 1, p = 1; else if (st == 2) cnt++, p++; else if (cnt == 0) { res.emplace_back(st, p); st = 2, cnt = 1, p = 1; } else cnt--, p++; } } res.emplace_back( st , p ); if( res.size() == 1 ){ cout << "1\n"; for( int i = 1 ; i <= n ; i ++ ) cout << "1 "; cout << "\n"; return; } cout << "2\n"; for (auto [a, b]: res) { while (b) cout << a << " ", b--; } cout << "\n"; return; } int32_t main() { ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); int t; cin >> t; while (t--) solve(); return 0; }

5|0E. Playoff Fixing


首先对于某回合中那些人输其实是固定的,比如k=3时,赢的人一定是1,2,3,4输的人一定是5,6,7,8

这样的话,要保证每一对中必须是一个前一半的和一个后一半的。这样的话只需要统计出后一半需要放的人是数量cnt这样就有cnt!种情况。如果出现一组中是1,1的情况,那就可以颠倒顺序,统计出可以颠倒顺序的组的数量p,然后就可以知道对于当前回合的方案数cnt!×2p,然后再递归的计算下一个回合即可。

#include <bits/stdc++.h> using namespace std; #define int long long const int mod = 998244353; vector<int> fact; int power(int x, int y) { int ans = 1; while (y) { if (y & 1) ans = ans * x % mod; x = x % mod * x % mod, y >>= 1; } return ans; } int calc(int k, vector<int> a) { if (k == 0) return 1; int mid = 1ll << (k - 1); int cnt = 0, p = 0; vector<int> b(1, 0); for (int i = 1; i < a.size(); i += 2) { if (a[i] > a[i + 1])swap(a[i], a[i + 1]); if (a[i] == -1 && a[i + 1] == -1) cnt++, p++, b.push_back(-1); else if (a[i] != -1 && a[i + 1] == -1) { if (a[i] > mid) return 0; b.push_back(a[i]), cnt++; } else if (a[i] == -1 && a[i + 1] != -1) { if (a[i + 1] <= mid) b.push_back(a[i + 1]), cnt++; else b.push_back(-1); } else { if (a[i] > mid || a[i + 1] <= mid) return 0; b.push_back(a[i]); } } return fact[cnt] * power(2, p) % mod * calc(k - 1, b) % mod; } int32_t main() { ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int k, n; cin >> k, n = 1 << k; fact = vector<int>(n + 1); fact[0] = 1; for (int i = 1; i <= n; i++) fact[i] = fact[i - 1] * i % mod; vector<int> a(n + 1); for (int i = 1; i <= n; i++) cin >> a[i]; cout << calc(k, a); return 0; }

6|0F. Editorial for Two


二分答案。枚举出时间后,通过优先队列可以计算出规定时间内前缀可以解决的数量和后缀可以解决的数量。然后后就可以求出最多可以解决的数量。

#include <bits/stdc++.h> using namespace std; #define int long long int read() { int x = 0, f = 1, ch = getchar(); while ((ch < '0' || ch > '9') && ch != '-') ch = getchar(); if (ch == '-') f = -1, ch = getchar(); while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar(); return x * f; } void solve() { int n = read(), k = read(); vector<int> a(n); for (auto &i: a) i = read(); auto check = [n, a, k](int x) { vector<int> b(n); priority_queue<int> q; int sum = 0; for (int i = 0; i < n; i++) { sum += a[i], q.push(a[i]); while( sum > x ) sum -= q.top() , q.pop(); b[i] = q.size(); if( b[i] >= k ) return true; } sum = 0 , q = priority_queue<int>(); for( int i = n-1 ; i >= 0 ; i -- ){ sum += a[i] , q.push(a[i]); while( sum > x ) sum -= q.top() , q.pop(); if( i > 0 && q.size() + b[i-1] >= k) return true; else if( i == 0 && q.size() >= k ) return true; } return false; }; int l = 0 , r = 1e18 , mid , res; while( l <= r ){ mid = ( l + r ) >> 1; if( check(mid) ) res = mid , r = mid - 1; else l = mid + 1; } cout << res << "\n"; return; } int32_t main() { for (int t = read(); t; t--) solve(); return 0; }

__EOF__

本文作者PHarr
本文链接https://www.cnblogs.com/PHarr/p/17444581.html
关于博主:前OIer,SMUer
版权声明CC BY-NC 4.0
声援博主:如果这篇文章对您有帮助,不妨给我点个赞
posted @   PHarr  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示