牛客白月赛29题解
Posted 辉小歌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客白月赛29题解相关的知识,希望对你有一定的参考价值。
https://ac.nowcoder.com/acm/contest/8564
目录
进攻【贪心+二分】
前缀最大数组,然后二分找。
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e6+10;
const int mod=1e9+7;
int n,m,a[N],maxv[N],b[N],x[N],y[N];
struct nodeint x,y;;
vector<node>ve;
map<int,int>mp;
int main(void)
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=m;i++) cin>>x[i];
for(int i=1;i<=m;i++) cin>>y[i];
for(int i=1;i<=m;i++) mp[x[i]]=max(mp[x[i]],y[i]);
for(auto i=mp.begin();i!=mp.end();i++)
ve.push_back(i->first,i->second);
maxv[0]=max(ve[0].y,0);
for(int i=1;i<ve.size();i++) maxv[i]=max(maxv[i-1],ve[i].y,0);
for(int i=0;i<ve.size();i++) b[i]=ve[i].x;
int k=ve.size();
LL ans=0;
for(int i=1;i<=n;i++)
int index=lower_bound(b,b+k,a[i])-b;
index--;
if(index<0) continue;
ans+=maxv[index];
cout<<ans;
return 0;
二进制【位运算 思维】
位运算的题目大部分都是只需考虑各个位即可。
本题,只需操作三次即可。与,或,异或个一次。
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef pair<int,int> pii;
vector<pii>ve;
int main(void)
int n; cin>>n;
for(int i=0;i<n;i++)
int a,b; cin>>a>>b;
ve.push_back(a,b);
int a=(1<<20)-1,b=0,c=0;//与 或 异或 a=全1 目的是任意一个数与都是本身
for(int i=0;i<20;i++)
int w1=0,w2=1;//当前位是0 当前位是1
for(int j=0;j<ve.size();j++)
int op=ve[j].x,w=ve[j].y;
int now=0;
if(w>>i&1) now=1;
if(op==1)
w1=w1&now;
w2=w2&now;
if(op==2)
w1=w1|now;
w2=w2|now;
if(op==3)
w1=w1^now;
w2=w2^now;
if(w1==0&&w2==0) a-=(1<<i); //说明不管是啥结果都是0 故该为一定与一个0
if(w1==0&&w2==1) ;//说明啥都不变,故各个操作也不变
if(w1==1&&w2==0) c+=(1<<i); //说明我们该位看好取反了 故异或位一定为1
if(w1==1&&w2==1) b+=(1<<i); //一定或一个1
cout<<3<<endl;
cout<<1<<" "<<a<<endl;
cout<<2<<" "<<b<<endl;
cout<<3<<" "<<c<<endl;
return 0;
积木【构造】
构造题咕咕了。
种树【贪心】
贪心,先用完小的再用大的。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
int n,m,ans,l[N],r[N],w[N],d[N];
void dfs(int u,int d)
if(!l[u])//不是叶子
if(d<=m) ans=max(ans,w[u]);//且可以是大剪刀
return;
dfs(l[u],d+1),dfs(r[u],d+1);
int main(void)
cin>>n;
for(int i=1;i<=n;i++)
int a,b; cin>>a>>b;
l[i]=a,r[i]=b;
for(int i=1;i<=n;i++) cin>>w[i];
for(int i=1;i<=n;i++) if(l[i]&&r[i]) m++;
m=(m+1)/2;//大剪刀
dfs(1,0);
cout<<ans<<endl;
return 0;
考试
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
const int mod=1e9+7;
int n,m,a[N],b[N];
int main(void)
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
int cnt=0;
for(int i=1;i<=n;i++) if(a[i]==b[i]) cnt++;//相等的
int ans=min(cnt,n-m)+min(n-cnt,m);
cout<<ans;
return 0;
项链【双链表模拟】
咕咕了
涂色
#include<stdio.h>
int main(void)
int n,sum=0;
while( scanf("%d",&n) != EOF )
sum=n+1;
printf("%d\\n",sum%998244353);
圆【圆的相切】
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long int LL;
int main(void)
int t; cin>>t;
while(t--)
LL x1,y1,r1,x2,y2,r2; cin>>x1>>y1>>r1>>x2>>y2>>r2;
LL len=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
if(len<(r1-r2)*(r1-r2))
puts("NO");
continue;
if(len<=(r1+r2)*(r1+r2)) puts("YES");
else puts("NO");
return 0;
/*
1、两圆外离。两圆距离大于两圆半径之和;
2、两圆外切。两圆距离等于两圆半径之和;
3、两圆相交。两圆距离小于两圆半径之和;
4、两圆内切。两圆距离等于大圆半径减小圆的半径;
5、两圆内含。两圆距离小于大圆的半径减小圆的半径。
*/
修改【思维 构造最小生成树】
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5*5+10;
int p[N],n,m;
struct nodeint a,b,c;;
bool cmp(node a,node b)return a.c<b.c;
vector<node>ve;
int find(int x)
if(x!=p[x]) p[x]=find(p[x]);
return p[x];
void solve()
for(int i=1;i<=n;i++) p[i]=i;
sort(ve.begin(),ve.end(),cmp);
LL sum=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);
sum+=c;
map<int,int>mp;
for(int i=1;i<=n;i++) mp[find(i)]++;
if(mp.size()==1) cout<<sum;
else puts("-1");
int main(void)
cin>>n>>m;
for(int i=1;i<=m;i++)
int a,b,c; cin>>a>>b>>c;
ve.push_back(a,b+1,c);
solve();
return 0;
克隆【欧拉序列】
就是求欧拉序列,然后分组输出即可。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
int n,m,k;
int h[N],e[N],ne[N],idx,len,ans[N];
vector<int>ve;
stack<int>st;
map<int,int>mp;
void add(int a,int b)
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
void dfs(int u)
mp[u]=1;
ans[++len]=u;
for(int i=h[u];i!=-1;i=ne[i])
int j=e[i];
if(mp[j]) continue;
dfs(j);
ans[++len]=u;
return;
int main(void)
memset(h,-1,sizeof h);
cin>>n>>m>>k;
while(m--)
int a,b; cin>>a>>b;
add(a,b),add(b,a);
dfs(1);
puts("YES");
int w=ceil(2.0*n/k);
queue<int>q;
for(int i=1;i<=len;i++) q.push(ans[i]);
for(int i=1;i<=k&&q.size();i++)
int temp=min(w,(int)q.size());
cout<<temp;
for以上是关于牛客白月赛29题解的主要内容,如果未能解决你的问题,请参考以下文章