写在前面
打这场之前上了一节基础课,一个sb题,我WA了一发,然后罚时最后倒二hhh,
发现自己状态严重不对,所以这场就没打了,
早上 vp 的,rk4100+,E 思路对了,就是写不对,哎哎哎,太菜
果然连续 3 天没怎么睡觉身体还是撑不住了
A
直接枚举每个子数组即可
void Solve(){
cin >> n;
vector<int> num(n+1);
For(i,1,n) cin >> num[i];
int ans = 0;
For(i,1,n){
int tmp = 0;
For(j,i,n){
tmp += num[j];
int avg = tmp/(j-i+1);
ans = max(ans,avg);
}
}
cout << ans << '\n';
}
B
把 0 全删了就行
void Solve(){
cin >> n >> s;
cout << count(all(s),'0') << '\n';
for(int i=0;i<n;++i){
if(s[i]=='0') cout << i + 1<< ' ';
}cout<<'\n';
}
C
注意到 msb(a) < msb(b),无解,否则,先将 a0 b1 的地方加上,再将 a1 b0 的地方减掉就行了
操作最多两次
void Solve(){
int a,b;
cin >> a >> b;
if(__lg(a) < __lg(b)) {
cout << "-1\n";
return;
}
if(a==b) {cout<<"0\n";}
else{
int A = 0, B = 0;
for(int i = __lg(a); i>=0; --i){
int u = (a>>i & 1), v = (b>>i & 1);
// cerr << u << ' ' << v << '\n';
if(u == 0 && v == 1) A += (1ll << i);
if(u == 1 && v == 0) B += (1ll << i);
}
// cerr << A << ' ' << B << '\n';
int ans = (A>0) + (B>0);
cout<<ans<<'\n';
if(A) cout << A << ' ';
if(B) cout << B;
cout<<'\n';
}
}
D
考虑分治,从中点往两边查询端点,如果 sum1 < sum2,则有可能存在端点,否则不可能
以左端点为例,只要一直往左走,不能走了往右走,到了一个点就返回了,需要查两次,右端点类似
但是这样查两端的次数是 4*15 = 60 次,发现操作是区间每个数字 +1, 则区间长度就是 和的差值,即 len = tot2 - tot1
所以只要找一个点就能一次查询长度得到另一个点,次数最多 30,结束
int ask(int op, int l, int r){
cout << op <<" " << l << ' ' << r <<endl;
int res;cin >> res;
return res;
}
void answer(int l,int r){
cout << "! " << l << ' ' << r << endl;
}
int work(int l,int r){
if(l == r) return l;
int mid = l+r >> 1;
int res1 = ask(1,l,mid), res2 = ask(2,l,mid);
if(res1 < res2){
return work(l,mid);
}else return work(mid+1,r);
}
// 1.区间+1,长度可知,
// 2.只要一个点就好了
void Solve(){
cin >> n;
int sum = ask(2,1,n), len = sum - n*(n+1)/2;
int l = work(1,n), r = l + len - 1;
answer(l,r);
}
E
发现只要让新增加的数字与前两个数字不等就能保证回文,但是第一个数字要特判掉
发现,由于 x 的取值最多为 n,而回文数组又一定有某些数字无法出现,否则无法形成回文,例如排列
那么,第一个数字直接取值为第一个未出现的数字就肯定不会形成回文(每个数字都能作为回文对称点,所以 a1 ~ an 都有可能),如果都出现了,选 1 就行
然后构造剩下的 k-1 个,其实只要 1 2 3 三个数字即可,保证与前两个数字不等,可以边枚举边维护前两个点就完了
// 1. 只要与前两个不同即可
// 2. 第一个数字直接选没有出现的数字,否则只要 1 2 3 就行了
void Solve(){
cin >> n >> k;
set<int> st;
For(i,1,n) st.insert(i);
vector<int> num(n+1);
For(i,1,n) cin >> num[i], st.erase(num[i]);
int a = num.back(), b = num[n-1];
if(a == b) b = num[n-2];
int c;
if(st.size()){
c = *st.begin();
}else{
c = 1;
while(a == c || b == c) ++c;
}
cout << c << ' ';
num.pb(c);
for(int i=1;i<k;++i){
int a = num.back(), b = num[(int)num.size()-2];
int c = 1;
while (c==a || c==b) ++c;
cout << c << ' ';
num.pb(c);
}
cout << '\n';
}

浙公网安备 33010602011771号