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;
}