牛客周赛 Round 52题解

A.两数之和

签到题,只要z大于2就“YES”,然后输出1和z-1

#include<iostream>
using namespace std;

int main()
{
	int z;
	cin>>z;
	if(z<3)
	cout<<"NO";
	else
	{
		cout<<"YES"<<endl;
		cout<<"1 "<<z-1;
	}
}

B.小红装匣子

a类型是1x2,b类型是1x3,总面积为2xn两层,全部化简为一层,定义一个k代表最多需要b的个数(n/3(需要b的总数)和b/2(总共有多少个b)两种情况,求最小值),剩余的用a来补全(n-k*3)

#include<iostream>
#include<algorithm>
using namespace std;

int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		long long a,b,n;
		cin>>a>>b>>n;
		if(a>=n)
		cout<<"YES"<<endl;
		else
		{
			long long k;
			k=min(b/2,n/3);
			if(a>=n-k*3)
			cout<<"YES"<<endl;
			else
			cout<<"NO"<<endl;
		}
	}
}

 C.小红的数字对对碰

0^a=a,a^a=0,负数^正数=负数,不同的负数互相异或=正数,0^负数=负数,相同负数异或是0
定义map函数,分别求出负数a和零b的个数以及每两个相同正数相互抵消后的正数c的个数。ab相互抵消得k,如果k代表负数,则(k+b)%2,否则c+b%2,得到的就是结果。

//0^a=a,a^a=0,负数^正数=负数,不同的负数互相异或=正数,0^负数=负数,相同负数异或是0
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;

int main()
{
	int n;
	cin>>n;
	map<int,int> mp;
	for(int i=1;i<=n;i++)
	{
		int k;
		cin>>k;
		mp[k]++;
	}
	int a=0,b=0,c=0;
	int x,y;
	for(auto it:mp)
	{
		x=it.first;
		y=it.second;
		if(x<0)
		a+=y;//统计负数 
		else if(x==0)
		b+=y;//统计零 
		else
		c+=y&1;//相同正数异或为零 
	}
	int h;
	h=min(a,c);
	a-=h;
	c-=h;
	cout<<((a+b)&1)+c; 
}

 D.小红的最大字典序

这个题要用到priority_queue(优先队列),详细过程看下面代码。

#include<iostream>
#include<queue>
using namespace std;
priority_queue<pair<char,string>> q;//优先队列(priority_queue) 
int main()
{
	int n; 
	cin>>n;
	string s;
	for(int i=1;i<=n;i++)
	{
		cin>>s;
		q.push({s[0],s});
	}
	string ans;
	ans="";
	while(!q.empty())
	{
		char c=q.top().first;
		string s=q.top().second;
		q.pop();
		ans+=c;
		s.erase(0,1);
		if(s!="")
		q.push({s[0],s});
	}
	cout<<ans;
}

 E.小红的图上加边

并查集路径压缩

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5+7;
long long a[N],fa[N];
int find(int x)
{
	return (fa[x]==x)?x:(fa[x]=find(fa[x]));
}
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		fa[i]=i;
	}
	for(int i=1;i<=m;i++)
	{
		int j,k;
		cin>>j>>k;
		j=find(j);
		k=find(k);
		if(j!=k)
		{
			fa[k]=j;
			a[j]=max(a[j],a[k]);
		}
	}
	long long ans=0;
	long long mn=1e9;
	for(int i=1;i<=n;i++)
	{
		if(fa[i]==i)
		{
			ans+=a[i];
			mn=min(mn,a[i]);
		}
	}
	cout<<ans-mn;
}

 F.小红的括号串

这个用到组合数。

设字符串个数为n,'(' = a ,')' = b ,'?' = c ,将c分为c1和c2,c1给a,c2给b。

{

        a+b+c=n;

        a+c1=b+c2;

}

可得c1=n/2-a

求C(c,c1)

这个暂时我不会,后期补

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值