【CodeForces训练记录】Codeforces Round 981 (Div. 3)
https://codeforces.com/contest/2033
训练情况
22队长率先开出E题,但是结局可能还是掉分了 TAT
赛后反思
这场太板了,D题有点反常(存疑?)
A题
我们直接模拟位置的变化就行,先手 \(-2 \times i - 1\) 后手 \(+ 2 \times i - 1\),用一个while找到 \(>n\) 的地方来结束循环即可。
#include <bits/stdc++.h>
#define int long long
using namespace std;
void solve(){
int n; cin>>n;
int now = 0;
int i = 0;
bool flag = false;
while(abs(now)<=n){
i++;
if(!flag) now -= 2*i-1;
else now += 2*i-1;
flag = !flag;
}
if(flag) cout<<"Sakurako"<<endl;
else cout<<"Kosuke"<<endl;
}
signed main(){
int T; cin>>T; while(T--)
solve();
return 0;
}
B题
我们考虑对角线要尽可能大,操作一次尽可能覆盖最多的点,所以我们只需要维护正方形上每条对角线负数绝对值的最大值即可,最后求和。
#include <bits/stdc++.h>
#define int long long
using namespace std;
void solve(){
int n; cin>>n;
vector<vector<int>> a(n+1,vector<int>(n + 1));
for(int i = 1;i<=n;i++){
for(int j = 1;j<=n;j++){
cin>>a[i][j];
}
}
vector<int> vis(3*n + 1);
for(int i = 1;i<=n;i++){
for(int j = 1;j<=n;j++){
if(a[i][j]<0) vis[i+n-j] = max(vis[i+n-j],-a[i][j]);
}
}
int ans = 0;
for(int i = 1;i<=3*n;i++) ans+=vis[i];
cout<<ans<<endl;
}
signed main(){
int T; cin>>T; while(T--)
solve();
return 0;
}
C题
一个我不会证明的贪心,我们考虑换之前和换之后对答案的贡献,如果换之后答案更小就换,最后再找 \(a_i = a_{i-1}\) 的对数即可。
#include <bits/stdc++.h>
#define int long long
using namespace std;
void solve(){
int n; cin>>n;
vector<int> a(n + 3);
for(int i = 1;i<=n;i++) cin>>a[i];
for(int i = 1;i<=n/2;i++){
int j = n-i+1;
int cnt1 = 0;
int cnt2 = 0;
if(a[i] == a[i-1]) cnt1++;
if(a[j] == a[j+1]) cnt1++;
if(a[j] == a[i-1]) cnt2++;
if(a[i] == a[j+1]) cnt2++;
if(cnt1 > cnt2) swap(a[i],a[j]);
}
int ans = 0;
for(int i = 2;i<=n;i++){
if(a[i] == a[i-1]) ans++;
}
cout<<ans<<endl;
}
signed main(){
int T; cin>>T; while(T--)
solve();
return 0;
}