【牛客训练记录】牛客周赛 Round 81
训练情况

赛后反思
C题刚开始用暴力等差数列求和塞到一个数组里去二分了,没有办法覆盖到 \(l,r\) \(10^{18}\) 的值域
A题
相等或公差为 \(1\) 的情况,我们对三个数直接排序判断即可
点击查看代码
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'
using namespace std;
void solve(){
int a[3];
cin>>a[0]>>a[1]>>a[2];
sort(a,a+3);
if(a[0] == a[1] && a[1] == a[2]) cout<<"Yes"<<endl;
else if(a[1] == a[0] + 1 && a[2] == a[1] + 1) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
signed main(){
// int T; cin>>T; while(T--)
solve();
return 0;
}
B题
直接暴力 \(O(n^2)\) 枚举每一位判断左下和右下的元素是否符合条件即可
点击查看代码
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'
using namespace std;
void solve(){
int n; cin>>n;
vector<vector<int>> a(n + 1,vector<int>(n + 1));
bool flag = true;
for(int i = 1;i<=n;i++){
for(int j = 1;j<=i;j++){
cin>>a[i][j];
}
}
for(int i = 1;i<n;i++){
for(int j = 1;j<=i;j++){
if(!(a[i][j] <= a[i+1][j] && a[i][j] <= a[i+1][j+1])) flag = false;
}
}
if(flag) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
signed main(){
int T; cin>>T; while(T--)
solve();
return 0;
}
C题
手玩样例可以发现,若 \(l,r\) 所在行大于一行则必定大的数会翻到上面,必定不成立,对于所在行差一行的情况,则需要判断两行的列是否相交,若相交必定有一位不满足条件,对于同一行的情况无论如何选都满足条件,现在我们的问题就是求数字 \(l,r\) 在哪一行的哪一列,首先前 \(i\) 行可以通过等差数列求和,我们直接二分判断在哪一行即可,知道了列就可以算上一行的最后一位,列就是差值了
点击查看代码
#include <bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define endl '\n'
using namespace std;
vector<int> c;
vector<int> p;
bool pd(int x,int total){
return x*(x-1)/2 < total;
}
int b(int total){
int l = 1,r = 1e9,m;
while(l<r){
m = l + r + 1 >> 1;
if(pd(m,total)) l=m;
else r=m-1;
}
return l;
}
void solve(){
int n,l,r; cin>>n>>l>>r;
int lx = b(l);
int ly = l-(lx*(lx - 1)/2);
int rx = b(r);
int ry = r-(rx*(rx - 1)/2);
// cout<<lx<<" "<<ly<<" "<<rx<<" "<<ry<<endl;
if(lx == rx) cout<<"YES"<<endl;
else if(lx == rx - 1 && ly > ry) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
signed main(){
for(int i = 1;i<=1e7;i++) c.emplace_back(i);
int sum = 0; for(int i = 0;i<1e7;i++) sum += c[i],p.emplace_back(sum);
int T; cin>>T; while(T--)
solve();
return 0;
}

浙公网安备 33010602011771号