2023河南萌新联赛第(三)场:郑州大学(B\C\D\F\H\L)

B、入门mex

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

一、题目要求

mex在许多题目中都有所考察,本题就来带大家入门mex

我们规定一些数字的mex是指满足下列要求的数字x

1、对于所有0≤y<x,y都在这些数字里出现过

2、x没有在这些数字里出现过

例如{1,2,3}的mex是0,{0,1,2,3,6,5}的mex是4

你也可以这样理解,一些数字的mex是从0往上枚举,第一个没出现的数字。

现在给你大小为n的数组a,请你回答选最多k个数字,mex最大是多少?

输入描述:

第一行两个整数n和k

接下来一行n个数字表示数组a

1≤k≤n≤10^5,0≤ai≤10^9

输出描述:

输出一行一个整数表示你的答案

示例1

输入

7 3
2 0 2 3 2 1 9

输出

3

说明

选三个数,最优方案是选0,1,2,mex为3

二、思路

1.可以随便选取k个数字,看谁的mex最大

2.如果整个数组里面没有0,则无论k为多少,它们最大的mex均为0

3若有0出现,则选取k个不同的数,最好这k个数字连续

例如:012的mex是3,025的mex则是1

即从0往上枚举第一个没有出现的数字

(ps:一定要读懂题意,本来一直以为是选择连续k个数字,就一直在wa)

三、代码

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int inf=0x3f3f3f3f;
const int N=1e5+10;
int a[N],b[N];
int n,k;
void solve()
{
	int i,j;
	cin>>n>>k;
	for(i=0; i<n; i++)
	{
		cin>>a[i];
	}
	sort(a,a+n);
	if(a[0]!=0)
	{
		cout<<"0"<<'\n';
	}
	else
	{
		int p=0;
		for(i=0; i<n; i++)
		{
			if(a[i]!=a[i+1])
			{
				b[p++]=a[i];
			}
		}
		int ans=1;
		for(i=1; i<=k-1; i++)
		{
			if(b[i]!=ans)
				break;
			else
				ans++;
		}
		cout<<ans<<endl;
	}
}
signed main()
{
	int t=1;
	while(t--)
	{
		solve();
	}
	return 0;
}

C、计数问题

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

一、题目要求

首先,出题人将给你一个正整数n

其次,你需要给出有多少种方案,使得A、B、C、D四个数字都是正整数且A∗B+C∗D=n

两个方案不同当且仅当A、B、C、D至少有一个数字不同,例如1∗1+3∗1和1∗1+1∗3是不同的两个方案

可以证明,1≤n≤1e5时答案小于等于9∗10^18所以不需要取余

输入描述:

一行一个正整数nnn,保证1≤n≤10^5

输出描述:

输出一个整数表示你的答案

示例1

输入

4

输出

8

说明

八种方案分别为(1,1,1,3),(1,1,3,1),(1,2,1,2),(1,2,2,1),(1,3,1,1),(2,1,1,2),(2,1,2,1),(3,1,1,1)

示例2

输入

1

输出

0

二、思路

1如果要算有几种方案,可以用左半部分的方案数乘以右半部分的方案数

例如当n=4的时候

f[4]=f[1]*f[3]+f[2]*f[2]+f[3]*f[1]=1*2+2*2+2*1=8

f[1]代表的是1 的因子个数   f[1]=1

f[2]代表的是2的因子个数   f[2]=2

f[3]代表的是3的因子个数   f[3]=2

三、代码

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=1e5+10;
int n,f[N],ans;
signed main()
{
	cin>>n;
	int i,j;
	for(i=1;i<=100000;i++)
	{
		for(j=1;j<=i/j;j++)
		{
			if(i%j==0)
			{
				f[i]++;
				if(i/j!=j)
				    f[i]++;
			}
		}
	}
	for(i=1;i<n;i++)
	{
		ans+=f[i]*f[n-i];
	}
	cout<<ans<<endl;
	return 0; 
}
/*
思路:
例如:f[4]=f[1]*f[3]+f[2]*f[2]+f[3]*f[1]; 
*/

D、AND and SUM

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

一、题目要求

给定两个整数a 和 s,问是否存在两个非负整数满足:

x&y=a

x+y=s
如果存在,输出 `Yes`,如果不存在输出`No`。

因为本题比较简单,数据给了多次查询。

输入描述:

第一行一个整数T,表示查询次数。

接下来T行,每行两个整数:a和s。

数据保证1≤T≤10^5,0≤a,s≤2^60;

输出描述:

T行,每行按要求输出`Yes`或者`No`。

示例1

输入

2
1 8
4 2

输出

Yes
No

二、思路

&(按位与):1&1=1,1&0=0,0&0=0,0&1=0

假设a的二进制数为101

x:101

y:1?1,

a:101

如果想要x&y==a,则需要满足s-a的那个数字y的二进制数中1的位置要等于a中二进制数1 的位置

三、代码

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
int s,a,t;
signed main()
{
	cin>>t;
	while(t--)
	{
		cin>>a>>s;
		if(a>s)
		{
			cout<<"No"<<'\n';
		}
		else
		{
			int x=s-a;
			int y=a;
			int ans=x&y;
			if(ans==a)
				cout<<"Yes"<<'\n';
			else
			    cout<<"No"<<'\n';
		}
	}
	return 0;
}

  • 16
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值