牛客白月赛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题解的主要内容,如果未能解决你的问题,请参考以下文章

牛客白月赛8题解

牛客白月赛4 题解

牛客白月赛11题解

牛客白月赛12题解

牛客白月赛10题解

牛客白月赛14题解