牛客小白赛40题解

A题

题意:一个数字x,问最少操作多少次变成0,操作如下:

二进制下1的个数是奇数,最低位取反,否则最高位取反

解:按照题意模拟一下就可以。

因为2次操作都至少会去掉一个最高位,所以次数一定不会很多

每次统计一下二进制下1出现的次数,奇数就异或1(最低位),偶数就异或最高位即可啦~~

ps:懒得写快读也过了

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
ll x;
int t,ans;

int main()
{
	std::ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin>>t;
	while(t--)
	{
		ans = 0;
		while(x)
		{
			ans++;
			ll k = x;
			int s = 0,r = 0;
			while(k)
			{
				r++;
				if(k & 1) s++;
				k /= 2;
			}
			if(s & 1) x ^= 1;
			else x ^= (1ll << (r - 1));
		}
		cout<<ans<<'\n';
	}
	return 0;
}

B题

题意:

解:

C题

D题

题意:通过插入字符使得给出的串的相邻字母不相同,问最后串的长度最小是多少

解:如果原串中两相邻字母相同,就势必要插入一个字母,从前往后扫描一遍,统计有多少对这样的相邻字母即可。

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;
int n,t;
char a[N];

int main()
{
	scanf("%d",&t);
	while(t--)
	{
		int ans;
		scanf("%s",a);
		n = strlen(a);
		ans = n;
		for(int i = 1;i < n; ++i)
			if(a[i] == a[i - 1]) ans++;
		printf("%d\n",ans);
	}
	return 0;
}

E题

题意:给出n个数,要求分成m组,每一组必须包含相同的数字,问人数最多的组最少多少人?

解:最大值最小化,很明显的二分答案求解。

二分人数最多的组有x人,暴力check,

求所有组都不超过x人,能够分成多少组,如果<=m组,那么答案可行,否则不可行

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
int t,ans,l,r,n,m,x;
map<int,int>q;

bool check(int x)
{
	int s = 0;
	for(auto k: q)
		s += k.second / x + (k.second % x != 0);
	return s <= m;
}

int main()
{
	std::ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin>>n>>m;
	for(int i = 1;i <= n; ++i) cin>>x,q[x]++;
	int l = 1,r = n;
	int ans = n + 1;
	while(l <= r)
	{
		int mid = (l + r) / 2;
		if(check(mid)) ans = min(ans,mid),r = mid - 1;
		else l = mid + 1;
	}
	if(ans == n + 1) cout<<"-1\n";
    else cout<<ans<<'\n';
	return 0;
}

F题

G题

题意:有n个人,每个人都有一个期望温度,当室内温度与期望温度差的绝对值不超过p,他就会很舒服,最多能有多少人感到舒服。

解:这题比较基础,支持区间修改和最大值查询的数据结构都可以做

我是差分做的,每个人感到舒服的都是一个区间,我们统计所有区间,在某个温度下,有多少线段覆盖就表示有多少人感到舒服。

#include <bits/stdc++.h>
using namespace std;

const int N = 3e6 + 10;
int n,t,p;
int a[N];
int s,ans;

int main()
{
	cin>>n>>p;
	for(int i = 1;i <= n; ++i)
	{
		int x;
		cin>>x;
		a[x]++,a[x + 2 * p + 1]--,s = max(s,x);
	}
	for(int i = 1;i <= s + 2 * p; ++i)
		a[i] += a[i - 1],ans = max(ans,a[i]);
	cout<<ans<<'\n';
	return 0;
}

I题

题意:需要给n个人排队,每个人有一个a[i],代表第i个人希望排在a[i]前面,问有多少种排队方式满足所有人。

解:一定一定要注意数据范围,n<=10,直接全排列判断是否符合条件即可。

10!=362800

#include<bits/stdc++.h>
using namespace std;

int a[12],b[12];
int ans,n;

int main()
{
	std::ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin>>n;
	for(int i = 1;i <= n; ++i) cin>>a[i];
	for(int i = 1;i <= n; ++i) b[i] = i;
	int ans = 0;
	do{
		int flag = 1;
		for(int i = 1;i <= n; ++i)
			for(int j = 1;j <= n; ++j)
			{
				if(b[j] == a[i]) break;
				if(b[j] == i) flag = 0;
			}
		if(flag) ans++;
	}while(next_permutation(b + 1,b + n + 1));
	cout<<ans<<'\n';
	return 0;
}
全部评论

相关推荐

bg27强双非本,目前在学习golang后端gin框架部分,在b站找了一个轮子项目敲了一下,技术栈是gin&nbsp;+&nbsp;gorm&nbsp;+&nbsp;mysql&nbsp;+&nbsp;redis。我目前的想法是这一个月学习408和go八股以及刷算法然后在12月找个寒假实习然后大三下开始准备考研。我是考研意愿比较强烈,想问一下我是应该all&nbsp;in其中一个方向吗,我感觉我实习对我考研来说也是没什么帮助的好像。
牛客28967172...:毕业工作,考研,考公是完全不同的方向。 99%的人拼尽全力也只能把一个做好(能做好都已经是佼佼者了,比如进进大厂,考985或者考公) 如果你确定要考研可以不用学任何就业技术框架,也不用实习经验,刷题背知识点就行,但注意必须考92院校起步,因为这个年代双非硕毕业后完全不如双非本(互联网行业),可以说双非硕在互联网就业完全是负收益
投递哔哩哔哩等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务