训练情况
赛后反思
大翻车,C题打表直接开猜,D题想到了转化行贡献再线段覆盖,但是不会算时间复杂度没敢写,后来试了一发给过了
A题
显然四个点都在坐标轴上,构成正方形只有四个数相等的情况
点击查看代码
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'using namespace std;void solve(){int a,b,c,d; cin>>a>>b>>c>>d;if(a == b && b == c && c == d) cout<<"Yes"<<endl;else cout<<"No"<<endl;
}signed main(){ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);int T; cin>>T; while(T--)solve();return 0;
}
B题
显然操作的先后顺序没什么关系,想要答案最大,根据三角形的两边和大于第三边,那我们选择第三边减一就可以满足了,选两个删掉插入两个的和减一,一直循环到只剩下一个就是答案
点击查看代码
#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];if(n == 1){cout<<a[1]<<endl;return;}int ans = a[1] + a[2] - 1;for(int i = 3;i<=n;i++){ans = ans + a[i] - 1;}cout<<ans<<endl;
}signed main(){ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);int T; cin>>T; while(T--)solve();return 0;
}
C题
直接打表开猜,我们发现 \(y\) 是二的次方+1,直接枚举指数,判断一下 \(y\) 必须严格小于 \(x\),如果满足条件直接输出,全部不满足条件输出 \(-1\) 即可
点击查看代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'using namespace std;int a[5] = {3,5,9,17,33};void solve(){int x; cin>>x;for(int i = 0;i<34;i++){int y = (1ll<<i)+1ll;if(y>=x) break;int z = x^y;if(x+y>z&&y+z>x&&x+z>y){cout<<y<<endl;return;}}cout<<-1<<endl;
}signed main(){ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);int T; cin>>T; while(T--)solve();return 0;
}
D题
注意到这题半径的限制,我们可以考虑将答案转化为行贡献的和,我们直接枚举每个圆心对某一行的贡献,我们先不考虑重叠问题,答案全部加起来,之后再维护一个行的线段覆盖,将重复计算的行上的点去掉即可,代码实现比较复杂
点击查看代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'using namespace std;void solve(){int n,m; cin>>n>>m;vector<int> x(n + 1),r(n + 1);for(int i = 1;i<=n;i++) cin>>x[i];for(int i = 1;i<=n;i++) cin>>r[i];vector<pair<int,int>> v[m+1];int ans = 0;for(int i = 1;i<=n;i++){for(int j = 0;j<=r[i];j++){int dis = sqrt(r[i]*r[i] - j*j);// cout<<i<<" "<<j<<" "<<dis<<endl;v[j].emplace_back(x[i]-dis,x[i]+dis);ans += 2*(dis*2 + 1);}ans -= (r[i]*2 + 1);}for(int i = 0;i<=m;i++){if(!v[i].size()) continue;sort(v[i].begin(),v[i].end());int l = v[i][0].first,r = v[i][0].second;for(int j = 1;j<v[i].size();j++){int ll = v[i][j].first;int rr = v[i][j].second;// cout<<ll<<" "<<yy<<endl;if(i == 0){if(ll <= r && rr >= r) ans -= (r-ll+1),r = max(r,rr);else if(ll<=r && rr <= r) ans -= (rr-ll+1),r = max(r,rr);else l = ll,r = rr;} else {if(ll <= r && rr >= r) ans -= 2*(r-ll+1),r = max(r,rr);else if(ll<=r && rr <= r) ans -= 2*(rr-ll+1),r = max(r,rr);else l = ll,r = rr;}}}cout<<ans<<endl;
}signed main(){ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);int T; cin>>T; while(T--)solve();return 0;
}