牛客小白月赛79
A O ( ) O(\sqrt) O()
签到
#include<bits/stdc++.h>
using namespace std;
int main(){
int n, res=0;
cin>>n;
while(n%2==1){
n/=10;
res++;
}
cout<<res;
return 0;
}
B O ( ) O(\sqrt) O()
签到
#include<bits/stdc++.h>
using namespace std;
int main(){
int n, s, minv=INT_MAX;
long long res=0;
cin>>n;
while(n--){
int x;
cin>>x;
if(x&1) s++, minv=min(minv, x);
res+=x;
}
if(s&1) res-=minv;
cout<<res;
return 0;
}
C
利用了一些 gcd 与 mex 的性质, 按照 mex 的大小分类, 思维
没想到
/*
// mex>=2
if(mex(1,n)>=2) res1=mex(1,n);
else res1=0;
// mex=1
if(a[i]=0) res_i=max(a[i-1], a[i+1]); // 两端特别考虑
// mex=0
F[l, r]=mex(l, r) * gcd(l, r)=0;
*/
#include<bits/stdc++.h>
using namespace std;
int n;
int const N = 1e5+10;
int a[N];
int op(){
set<int> q;
for(int i=1; i<=n; i++)
q.insert(a[i]);
for(int i=0;;i++){
if(!q.count(i)){
if(i>=2) return i;
return 0;
}
}
return 0;
}
int main(){
cin>>n;
for(int i=1; i<=n; i++) cin>>a[i];
a[0]=a[n+1]=INT_MIN;
int res=0;
for(int i=1; i<=n; i++){
if(a[i]==0){
int t=max(a[i-1], a[i+1]);
res=max(res, t);
}
}
res=max(res, op());
cout<<res;
return 0;
}
D O ( × ) O(\times) O(×)
不会, 了解一下取模与倍数的关系以及 bfs 如何反着预处理
解法二 O ( 2 20 + T ) O(2^{20}+T) O(220+T)
-
考虑在 2 20 2^{20} 220 的模意义下, 预处理 0 0 0 到数字 i i i 的射击次数
-
数字 x 可以变成 x+1 或 2x , 不妨 2x 和 x+1 向 x 建边
-
dist[i] 即为 i 变成 0 的次数
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
int n;
int const M = (1<<20);
int check(int x){
int s=0;
while((x&1)==0) x/=2, s++;
return s;
}
void Solution1(){
/*
O(T*20*20)
给你一个 n, 相当于让 n 的二进制右边存在 20 个 0
操作 1 : n 左移一位
操作 2 : n ++
我们发现, 1+2 一定不如 2+1 好
所以我们枚举先加几次 (小于20次), 在计算左移多少次
M | N 即为 : N 是 %M 条件的 0
*/
int res=2e9;
for(int add=0; add<20; add++){
int t=(n+add)%M; // 枚举加了多少次
if(!t){
res=min(res, add);
continue;
}
res=min(res, add+20-check(t));
}
cout<<res<<'\n';
}
struct Solution2{
int dist[M];
vector<int> e[M];
queue<int> q;
bool f=0;
void mem(){
if(f==1) return ;
for(int i=0; i<M; i++){
e[(i+1)%M].push_back(i);
e[(i*2)%M].push_back(i);
}
memset(dist, 0x3f, sizeof dist);
dist[0]=0; q.push(0);
while(q.size()){
auto u=q.front(); q.pop();
for(auto v:e[u]){
if(dist[v]>dist[u]+1){
dist[v]=dist[u]+1;
q.push(v);
}
}
}
f=1;
}
int ans(int x){
return dist[x];
}
}wpc;
void solve(){
cin>>n;
n%=M;
// Solution1();
wpc.mem();
cout<<wpc.ans(n)<<'\n';
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T = 1;
cin >> T;
while(T --){
solve();
}
return 0;
}
E
概率期望, 回头补
F
放弃
G
放弃