Codeforces Round #790 (Div. 4) A - H 題解
阿新 • • 發佈:2022-05-12
上次打了一場校賽,剛好和上次的 div2 衝了,最近又各種 ddl 轟炸,搞得沒啥時間寫題解
這場打下來感覺就是各種模板題
A. Lucky?
直接寫,前三個數字的和等於後三個數字的和
#include <iostream> #include <cstdio> #include <algorithm> #include <vector> #include <string> #include <queue> #include <functional> #include <map> #include <set> #include <cmath> #include <cstring> #include <deque> #include <stack> using namespace std; typedef long long ll; #define pii pair<int, int> const ll maxn = 2e5 + 10; const ll inf = 1e17 + 10; int main() { int t; cin >> t; while(t--) { int a = 0, b = 0; for(int i=0; i<3; i++) { int x; scanf("%1d", &x); a += x; } for(int i=0; i<3; i++) { int x; scanf("%1d", &x); b += x; } if(a == b) cout << "yes" << endl; else cout << "no" << endl; } return 0; }
B. Equal Candies
直接找到陣列的最小的,然後遍歷一次看看其他都要拿走多少
#include <iostream> #include <cstdio> #include <algorithm> #include <vector> #include <string> #include <queue> #include <functional> #include <map> #include <set> #include <cmath> #include <cstring> #include <deque> #include <stack> using namespace std; typedef long long ll; #define pii pair<int, int> const ll maxn = 2e5 + 10; const ll inf = 1e17 + 10; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int t; cin >> t; while(t--) { int n; cin >> n; int minn = 1e9 + 7; ll ans = 0; for(int i=0; i<n; i++) { ll x; cin >> x; minn = x < minn ? x : minn; ans += x; } cout << ans - minn * n << endl; } return 0; }
C. Most Similar Words
直接暴力跑一遍,代價的話就是兩個字母直接相減的絕對值
#include <iostream> #include <cstdio> #include <algorithm> #include <vector> #include <string> #include <queue> #include <functional> #include <map> #include <set> #include <cmath> #include <cstring> #include <deque> #include <stack> using namespace std; typedef long long ll; #define pii pair<int, int> const ll maxn = 2e5 + 10; const ll inf = 1e17 + 10; string s[maxn]; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int t; cin >> t; while(t--) { int n, m; cin >> n >> m; for(int i=0; i<n; i++) cin >> s[i]; int ans = m * 26; for(int i=0; i<n; i++) { for(int j=i+1; j<n; j++) { int now = 0; for(int k=0; k<m; k++) { int x = s[i][k] - s[j][k]; if(x < 0) x = -x; now += x; } ans = now < ans ? now : ans; } } cout << ans << endl; } return 0; }
D. X-Sum
類似於 N 皇后的狀態儲存,處理斜邊的和,左斜就是 x - y,右斜就是 x + y,然後陣列開大點就行
最後遍歷每一個點,代價是所屬的兩個斜邊的和 減去 自身的重複
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 210;
const ll inf = 1e17 + 10;
ll num[maxn][maxn];
ll l[maxn * 4], r[maxn * 4];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
int n, m;
cin >> n >> m;
for(int i=0; i<n; i++) for(int j=0; j<m; j++) cin >> num[i][j];
for(int i=0; i<maxn * 4; i++) l[i] = r[i] = 0;
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
l[200 + i - j] += num[i][j];
r[i + j] += num[i][j];
}
}
ll ans = 0;
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
ll now = l[200 + i - j] + r[i + j] - num[i][j];
ans = now > ans ? now : ans;
}
}
cout << ans << endl;
}
return 0;
}
E. Eating Queries
二分板子題
排序後做字首和,直接二分查詢
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
ll num[maxn];
bool cmp(ll a, ll b)
{
return a > b;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
int n, m;
cin >> n >> m;
for(int i=1; i<=n; i++) {cin >> num[i];}
sort(num + 1, num + 1 + n, cmp);
for(int i=1; i<=n; i++) num[i] += num[i-1];
num[n + 1] = inf;
while(m--)
{
ll x;
cin >> x;
ll way = lower_bound(num + 1, num + n + 2, x) - num;
if(way == n + 1) way = -1;
cout << way << endl;
}
}
return 0;
}
F. Longest Strike
這題做的時候卡了半小時
直接用 map 裝起來,然後遍歷一次,不連續或者小於 k 就斷開,然後記錄最長是多少
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
map<int, int>vis;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
int n, m;
cin >> n >> m;
for(int i=0; i<n; i++)
{
int x;
cin >> x;
vis[x]++;
}
int way = 0, now = 0, maxx = 0, ans = 0;
for(auto it=vis.begin(); it!=vis.end(); it++)
{
if(now != it->first)
{
way = 0;
now = it->first;
}
if(it->second < m)
way = 0;
else
{
way++;
if(way > maxx)
{
maxx = way;
ans = it->first;
}
}
now++;
}
if(maxx == 0) cout << "-1" << endl;
else cout << ans - maxx + 1 << " " << ans << endl;
vis.clear();
}
return 0;
}
G. White-Black Balanced Subtrees
簡單樹型 dp 模板題
從根開始搜,當前樹的黑白,通過先搜尋子樹的黑白數量,然後加起來,最後判斷一下當前樹是否符合平衡
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 4010;
const ll inf = 1e17 + 10;
vector<int>gra[maxn];
int l[maxn], r[maxn];
string s;
int dps(int now, int pre)
{
int ans = 0;
if(s[now-1] == 'W') l[now]++;
else r[now]++;
for(int i=0; i<gra[now].size(); i++)
{
int nex = gra[now][i];
if(nex == pre) continue;
ans += dps(nex, now);
l[now] += l[nex];
r[now] += r[nex];
}
return ans + (l[now] == r[now]);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
int n;
cin >> n;
for(int i=0; i<=n; i++) {l[i] = r[i] = 0; gra[i].clear();}
for(int i=2; i<=n; i++)
{
int x;
cin >> x;
gra[x].push_back(i);
}
cin >> s;
cout << dps(1, 1) << endl;
}
return 0;
}
H. Maximum Crossings
題目模型轉化過來就是求逆序對
考慮樹狀陣列 或者 歸併排序 \(O(nlogn)\)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
ll tr[maxn];
int n;
inline int lowbit(int x)
{
return x & (-x);
}
void add(int x, ll val)
{
for(int i=x; i<=n; i+=lowbit(i))
tr[i] += val;
}
ll query(int x)
{
ll ans = 0;
while(x)
{
ans += tr[x];
x -= lowbit(x);
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
{
cin >> n;
for(int i=0; i<=n; i++) tr[i] = 0;
ll ans = 0;
for(int i=0; i<n; i++)
{
ll x;
cin >> x;
ans += i - query(x - 1);
add(x, 1);
}
cout << ans << endl;
}
return 0;
}