【CodeForces训练记录】Codeforces Round 998 (Div. 3)
训练情况
赛后反思
div3 给罚时拉满了,C题 \(k-a_i=a_i\) 的情况错掉怒罚五发,D题成结论猜猜乐了,E题看错题了,以为是边一致,实则联通就行,又被并查集背刺了
A题
斐波那契第三位可以从第一二位算出来,也可以从第四五位算出来,两个答案取大值即可
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'
using namespace std;
void solve(){
int a,b,d,e; cin>>a>>b>>d>>e;
int ma = 0;
int c = a + b;
int ans = 0;
if(c == a + b) ans++;
if(d == b + c) ans++;
if(e == c + d) ans++;
ma = max(ans,ma);
ans = 0;
c = e - d;
if(c == a + b) ans++;
if(d == b + c) ans++;
if(e == c + d) ans++;
ma = max(ans,ma);
cout<<ma<<endl;
}
signed main(){
int T; cin>>T; while(T--)
solve();
return 0;
}
B题
我们可以找到 \(0 \sim n-1\) 对应的牛牛,这就是出牌顺序,接下来 \(n \sim nm-1\) 都按这个牛牛顺序出牌,如果有人没有这张牌就是无解情况,否则直接输出最开始的出牌顺序即可
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'
using namespace std;
void solve(){
int n,m; cin>>n>>m;
vector<vector<int>> a(n + 1,vector<int>(m + 1));
vector<int> pos(n*m*2);
for(int i = 1;i<=n;i++){
for(int j = 1;j<=m;j++){
cin>>a[i][j];
pos[a[i][j]] = i;
}
}
vector<int> ans;
for(int i = 0;i<n;i++) ans.push_back(pos[i]);
bool flag = true;
for(int i = n;i<n*m;i++){
if(ans[(i-n)%n] != pos[i]) flag = false;
}
if(flag){
for(int i = 0;i<n;i++) cout<<ans[i]<<" ";
} else {
cout<<-1;
}
cout<<endl;
}
signed main(){
int T; cin>>T; while(T--)
solve();
return 0;
}
C题
这题实则博弈论没有用,就是找数列中 \(a+b=k\) 的对数,因为无论和等不等 \(k\) 的一对,博弈时 Alice 为了让得分最小选择不能和等 \(k\) 的数时,一定还有另一个数给 Bob 选择,所以不会对最终答案造成贡献,这里注意一下 \(k-a_i=a_i\) 的情况,还有数组越界的问题就行
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'
using namespace std;
void solve(){
int n,k; cin>>n>>k;
vector<int> a(n + 1);
int ma = 0;
for(int i = 1;i<=n;i++){
cin>>a[i];
ma = max(ma,a[i]);
}
sort(a.begin() + 1,a.end(),greater<int>());
vector<int> cnt(ma+1);
for(int i = 1;i<=n;i++) cnt[a[i]]++;
int ans = 0;
for(int i = 1;i<=n;i++){
if(k-a[i] >= 1 && k-a[i] <= ma){
if(cnt[a[i]]&&cnt[k-a[i]]){
ans++;
cnt[a[i]]--;
cnt[k-a[i]]--;
if(cnt[a[i]]<0){
ans--;
cnt[a[i]]+=2;
}
}
}
}
cout<<ans<<endl;
}
signed main(){
int T; cin>>T; while(T--)
solve();
return 0;
}
D题
结论猜猜乐,因为两个数同减 min 不会改变相对大小关系,想要单调不减,前面的数就得小,盲猜一个全部操作再is_sorted判断单调给我猜对了
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'
using namespace std;
void solve(){
int n; cin>>n;
vector<int> a(n + 1);
for(int i = 1;i<=n;i++) cin>>a[i];
for(int i = 2;i<=n;i++){
int mi = min(a[i],a[i-1]);
a[i-1]-=mi;
a[i]-=mi;
}
// for(int i = 1;i<=n;i++) cout<<a[i]<<" ";
// cout<<endl;
if(is_sorted(a.begin() + 1,a.end())) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
signed main(){
int T; cin>>T; while(T--)
solve();
return 0;
}
E题
两个图联通的节点情况要一致,所以我们使用两个并查集分别维护 \(F\) 图和 \(G\) 图的联通块,先维护 \(G\) 图联通,按 \(G\) 图的联通情况去判断 \(F\) 图的联通情况,如果不一致则答案加一,一致则合并 \(G\) 图,然后按 \(F\) 图的联通情况去判断 \(G\) 图的联通情况,如果不一致则答案加一再合并 \(F\) 图。
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'
using namespace std;
const int N = 2e5 + 3;
int fa1[N],fa2[N];
int Find1(int x){
if(fa1[x] == x) return x;
return fa1[x] = Find1(fa1[x]);
}
int Find2(int x){
if(fa2[x] == x) return x;
return fa2[x] = Find2(fa2[x]);
}
void Union1(int x,int y){
x = Find1(x); y = Find1(y);
if(x == y) return;
fa1[y] = x;
}
void Union2(int x,int y){
x = Find2(x); y = Find2(y);
if(x == y) return;
fa2[y] = x;
}
void solve(){
int n,m,k; cin>>n>>m>>k;
for(int i = 1;i<=n;i++) fa1[i] = i,fa2[i] = i;
vector<int> u1(m + 1),v1(m + 1),u2(k + 1),v2(k + 1);
for(int i = 1;i<=m;i++){
cin>>u1[i]>>v1[i];
}
for(int i = 1;i<=k;i++){
cin>>u2[i]>>v2[i];
Union2(u2[i],v2[i]);
}
int ans = 0;
for(int i = 1;i<=m;i++){
if(Find2(u1[i]) != Find2(v1[i])){
ans++;
} else {
Union1(u1[i],v1[i]);
}
}
for(int i = 1;i<=k;i++){
if(Find1(u2[i]) != Find1(v2[i])){
Union1(u2[i],v2[i]);
ans++;
}
}
cout<<ans<<endl;
}
signed main(){
int T; cin>>T; while(T--)
solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!