牛客白月赛30题解
Posted 辉小歌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客白月赛30题解相关的知识,希望对你有一定的参考价值。
https://ac.nowcoder.com/acm/contest/9667#question
vp了一下,这场挺简单的。b题又是不擅长的线段树。
有时间将所有的线段树题补一下,线段树不想学,指挥最基础的果真不行。
不会线段树我也太菜了。
目录
黑白边【最小生成树】
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,m,p[N];
int find(int x)
if(x!=p[x]) p[x]=find(p[x]);
return p[x];
struct nodeint a,b,c;;
bool cmp(node a,node b)return a.c<b.c;
vector<node>ve;
void solve()
for(int i=1;i<=n;i++) p[i]=i;
sort(ve.begin(),ve.end(),cmp);
int ans=0;
for(int i=0;i<ve.size();i++)
int a=ve[i].a,b=ve[i].b,c=ve[i].c;
if(find(a)==find(b)) continue;
p[find(a)]=find(b);
ans+=c;
map<int,int>mp;
for(int i=1;i<=n;i++) mp[find(i)]++;
if(mp.size()!=1) cout<<-1;
else cout<<ans;
int main(void)
cin>>n>>m;
while(m--)
int a,b,c; cin>>a>>b>>c;
ve.push_back(a,b,c);
solve();
return 0;
最好的宝石【线段树 待补】
滑板上楼梯【思维】
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long int LL;
LL n;
int main(void)
cin>>n;
LL cnt=(n/4)*2;
n=n%4;
if(n==1) cnt++;
else if(n==2) cnt+=2;
else if(n==3) cnt++;
cout<<cnt;
return 0;
GCD【线性筛+思维】
- n<=3 一定是-1
- n>3 我们先将所有的质数拿出来,再拿出来1,再任意的拿一个非质数。
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int prime[N],st[N],cnt,n;
void init(int n)
for(int i=2;i<=n;i++)
if(!st[i]) prime[cnt++]=i;
for(int j=0;prime[j]<=n/i;j++)
st[i*prime[j]]=1;
if(i%prime[j]==0) break;
int main(void)
cin>>n;
init(n);
if(n<=3) puts("-1");
else cout<<cnt+2<<endl;
return 0;
牛牛的加法【模拟】
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long int LL;
LL n;
int main(void)
string a,b; cin>>a>>b;
int len=max(a.size(),b.size());
while(a.size()<len) a="0"+a;
while(b.size()<len) b="0"+b;
queue<int>q;
for(int i=0;i<a.size();i++)
int w=(a[i]-'0')+(b[i]-'0');
q.push(w%10);
while(q.size()>1&&q.front()==0) q.pop();
while(q.size()) cout<<q.front(),q.pop();
return 0;
石子合并【贪心】
找到最大的,让最大的挨个和其他配对。
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long int LL;
const int N=1e6+10;
LL n,a[N];
LL ans=0,maxv=0;
int main(void)
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i],maxv=max(maxv,a[i]);
for(int i=1;i<=n;i++) ans+=a[i]+maxv;
cout<<ans-maxv*2;
return 0;
滑板比赛【双指针】
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*3+10;
int n,m,a[N],b[N];
int main(void)
cin>>n>>m;
for(int i=0;i<n;i++) cin>>a[i];
for(int j=0;j<m;j++) cin>>b[j];
sort(a,a+n),sort(b,b+m);
int cnt=0;
for(int i=n-1,j=m-1;i>=0;i--)
while(j&&b[j]>=a[i]) j--;
if(j>=0&&b[j]<a[i]) cnt++,j--;
cout<<cnt;
return 0;
第 k 小【对顶堆】
#include<bits/stdc++.h>
using namespace std;
int n,m,k;
int main(void)
priority_queue<int>maxv;
priority_queue<int,vector<int>,greater<int>>minv;
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
int x; cin>>x;
if(maxv.size()<k) maxv.push(x);
else
minv.push(x);
if(maxv.top()>minv.top())
minv.push(maxv.top()); maxv.pop();
maxv.push(minv.top()); minv.pop();
while(m--)
int op; cin>>op;
if(op==1)
int x; cin>>x;
if(maxv.size()<k) maxv.push(x);
else
minv.push(x);
if(maxv.top()>minv.top())
minv.push(maxv.top()); maxv.pop();
maxv.push(minv.top()); minv.pop();
else
if(maxv.size()==k) cout<<maxv.top()<<'\\n';
else cout<<-1<<'\\n';
return 0;
区间异或【预处理】
预处理每一个长度的最大异或值。
正解还得加二分优化一下,这里懒得写了。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,m,a[N],s[N],maxv[N];
int main(void)
std::ios::sync_with_stdio(false);
std::cin.tie(0);
//如果编译开启了 C++11 或更高版本,建议使用 std::cin.tie(nullptr);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i],s[i]=s[i-1]^a[i];
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++)
int r=s[j],l=s[j-i];
maxv[i]=max(maxv[i],r^l);
while(m--)
int x; cin>>x;
int ans=1e9;
for(int i=1;i<=n;i++)
if(maxv[i]>=x) ans=i;
if(ans!=1e9) break;
if(ans==1e9) cout<<-1<<'\\n';
else cout<<ans<<'\\n';
return 0;
小游戏【DP】
f[i][0] 前i个位置,第i个位置不选
f[i][1] 前i个位置,第i个位置选
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5*2+10;
LL n,a[N],f[N][2],st[N];
int main(void)
//std::ios::sync_with_stdio(false);
//std::cin.tie(0);
//如果编译开启了 C++11 或更高版本,建议使用 std::cin.tie(nullptr);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i],st[a[i]]++;
vector<LL>ve;
ve.push_back(-1);
for(int i=1;i<N;i++) if(st[i]) ve.push_back(i);
n=ve.size()-1;
for(int i=1;i<=n;i++)
if(ve[i]-ve[i-1]>1)//相邻
f[i][0]=max(f[i-1][0],f[i-1][1]);
f[i][1]=max(f[i-1][0],f[i-1][1])+ve[i]*st[ve[i]];
else
f[i][0]=max(f[i-1][0],f[i-1][1]);
f[i][1]=f[i-1][0]+ve[i]*st[ve[i]];
cout<<max(f[n][0],f[n][1])<<endl;
return 0;
以上是关于牛客白月赛30题解的主要内容,如果未能解决你的问题,请参考以下文章