2024河南萌新联赛第(四)场 河南理工大学

B.小雷的神奇电脑

题目:

原题链接
给出量个数n,m,一个有n个数的数组,数组里每个数不超过2^m,求数组任意两个数同或后的最大值。同或定义:二进制下相同为1,不同为0。

思路:

观察同或的定义可以发现相邻的数同或得出的结果是最大的,所以我们需要先把数组排序,我先运用了异或的性质,用a[i]^a[i+1],求出异或后的最小值,然后再利用bitset把每一位都取反就是同或后的最大值。因为我定义的是31位数,所以需要把前len-m位数置0。最后转为10进制数就可以了。

AC代码:

#include <bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
const int N = 2e5 + 20;
int a[N], b[N], c[N];
//bitset<31> s;
int ans = INT_MAX;

signed main() {
	IOS
	int n, m, s = 0, x = 0, d;
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	sort(a + 1, a + n + 1);
//	for (int i = 1; i <= n; i++) {
//		int tt = a[i];
//		while (tt != 0) {
//			//cout << "-1" << '\n';
//			x = x * 10 + (tt % 2);
//			tt = tt / 2;
//			b[s]++;
//		}
//		//cout << x << '\n';
//		if (b[s] != b[s - 1] && s != 1 && s != 0)
//			break;
//		s++;
//		x = 0;
//		c[i] = a[i];
//	}
	//cout << s << '\n';
	for (int i = 1; i < n ; i++) {
		d = a[i] ^ a[i + 1];
		ans = min(ans, d);
	}
	bitset<31> q(ans);
	q.flip();
	string dd = q.to_string();

	int len = dd.size();
	for (int i = 0; i < len - m; i++)
		dd[i] = '0';

	//cout << dd << '\n';
	int cnt = 0;
	for (int i = 0; i < 31; i++) {
		cnt = cnt * 2 + (dd[i] - '0');
		//cout << dd[i] - '0' << " ";
	}
	cout << cnt << '\n';
}

C.岗位分配

题目:

原题链接
有众多志愿岗位需要被分配,给你志愿者人数和一个数组,数组中的值是每个地方至少要分配的人数,求可能的分配情况总数。

思路:

题目上说可以剩余,因为不管怎么分我们都要保证志愿岗位的最小志愿者人数,所以我们只需要讨论剩下的人怎么分配。
假设4个人需要分配到3个岗位中:
首先4可以分为(1,3),(2,2),(1,1,2),(4),如果是按照高中所学的隔板分配法,那么就是假设4个小球2个隔板,结果为 C_5^2=10;
这样我们明显是少了(1,3),(2,2)这两种含0的情况,所以我们要加上一个小球,令这个小球的价值为0,所以结果就是C_6^2=15。
这样,就可以得出:
0个人分配3个岗位 C_2^2=1
1个人分配3个岗位 C_3^2=3
2个人分配3个岗位 C_4^2=6
3个人分配3个岗位 C_5^2=10
4个人分配3个岗位 C_6^2=15
因此可以得出结论
在这里插入图片描述

AC代码:

#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
const int N=2e5+20;
const int mod=998244353;
int inv[N],fac[N];

//快速幂
int quick(int a,int b)
{
	int ans=1;
	while(b)
	{
		if(b&1)
		ans=(ans*a)%mod;
		b>>=1;
		a=(a*a)%mod;
	}	
	return ans;
}

void init()
{//求阶乘 
	fac[0]=1;
	for(int i=1;i<N;i++)
	fac[i]=fac[i-1]*i%mod;
	//求逆元
	inv[N-1]=quick(fac[N-1],mod-2);
	for(int i=N-2;i>=0;i--)
	inv[i]=inv[i+1]*(i+1)%mod; 
}

int s(int n,int m)
{
	if(m>n)
	return 0;
	if(m==0)
	return 1;
	return fac[n]*inv[m]%mod*inv[n-m]%mod;
}

signed main()
{
	IOS
	init();
	int n,m;
	cin>>n>>m;
	int sum=0;
	for(int i=0;i<n;i++)
	{
		int a;
		cin>>a;
		m-=a;
	}
	int ans=0;
	for(int i=0;i<=m;i++)
	ans=(ans+s(n+i-1,n-1))%mod;
	cout<<ans<<'\n';
}

D.简单的素数

题目:

原题链接
多实例,给出一个数x,是素数输出Yes,不是输出No。

思路:

签到题,暴力判断素数就可以了。

AC代码:

#include <bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;

signed main() {
	int t;
	cin >> t;
	while (t--) {
		int x, f = 1;
		cin >> x;
		int k = sqrt(x);
		for (int i = 2; i <= k; i++) {
			if (x % i == 0) {
				f = 0;
				cout << "No" << '\n';
				break;
			}

		}
		if (f == 1)
			cout << "Yes" << '\n';
	}
}

F.小雷的算式

题目:

原题链接
给出一个只含加法的式子,把数字从大到小排序后输出,并输出结果。

思路:

我是首先把这个式子中含的每一个数用数组储存起来,然后从小到大排序后取反,输出出来。然后再把每一个数相加,输出结果。

AC代码:

#include <bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;

const int N = 2e5 + 10;
int a[N];

signed main() {
	IOS
	string s;
	cin >> s;
	int x = 0, ans = 0;
	int len = s.size();
	for (int i = 0; i < len; i++) {
		if (s[i] != '+')
			a[x] = a[x] * 10 + (s[i] - '0');
		if (s[i] == '+')
			x++;
		//cout << x << '\n';
	}
	sort(a, a + x + 1);
	reverse(a, a + x + 1);
	for (int i = 0; i < x; i++)
		cout << a[i] << "+";
	cout << a[x];
	cout << '\n';
	for (int i = 0; i <= x; i++)
		ans += a[i];
	cout << ans << '\n';
}

H.聪明且狡猾的恶魔

题目:

原题链接
给出一个数x代表金币数量,n代表恶魔数量。需要让50%及以上的恶魔利益最大,求最多可以获得多少金币。

思路:

要想获得最大金币数量,当恶魔数量为偶数时只需要满足50%,给(n/2)-1只恶魔一只一个金币,那自己所获得的金币数量就是x-(n/2)+1;当奇数时,需要让(n/2)+1只满意,需要给(n/2)只恶魔一只一个,此时金币数量是x-(n/2)。

AC代码:

#include <bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;

signed main() {
	IOS
	int t;
	cin >> t;
	while (t--) {
		int x, n;
		cin >> x >> n;
		if (n % 2 != 0)
			cout << x - (n / 2) << '\n';
		else
			cout << x - (n / 2) + 1 << '\n';
	}
}
  • 26
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值