牛客小白月赛37部分题解

Posted 辉小歌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客小白月赛37部分题解相关的知识,希望对你有一定的参考价值。

A: 经此一役小红所向无敌【难度: 一般 / 知识点: 模拟】


计算出每一个人可以打的回合数,取一个较小的回合。

#include<bits/stdc++.h>
using namespace std;
long long int a,h,b,k;
int main(void)
{
	cin>>a>>h>>b>>k;
	long long int sum=0;
	int s1=h/b,s2=k/a;
	if(h%b) s1++;
	if(k%a) s2++;
    sum=min(s1,s2)*(a+b);
	if(s1>s2) sum+=a*10;
	if(s1<s2) sum+=b*10;
	cout<<sum;
	return 0;
}

B: 擅长解密的小红同学【难度: 中 / 知识点: 组合数学 数学期望】


#include<bits/stdc++.h>
using namespace std;
const int N=1e7+10;
const int mod=1e9+7;
typedef long long int LL;
int a[15];
LL f[N];
LL quick_mi(LL a,LL b,LL p)
{
	LL sum=1;
	while(b)
	{
		if(b&1) sum=(sum*a)%p;
		b=b>>1;
		a=(a*a)%p;
	}
	return sum%p; 
}
int main(void)
{
	LL sum1=0,sum2=1;
	for(int i=0;i<10;i++) cin>>a[i],sum1+=a[i];
	f[0]=1;
	for(int i=1;i<N;i++) f[i]=(f[i-1]*i)%mod;
	for(int i=0;i<10;i++) if(a[i]) sum2=(sum2*f[a[i]])%mod;
	cout<<(f[sum1]*quick_mi(sum2,mod-2,mod))%mod<<endl;
	return 0;
}

D: 比那名居的桃子【难度: 一般 / 知识点: 前缀和】


说白了就是在长度为n的数组里找一个长度为k的区间。然后要满足题目给的条件。
直接前缀和搞一下即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5+10;
LL a[N],b[N],s[N],ss[N],n,k;
int main(void)
{
	cin>>n>>k;
	for(int i=1;i<=n;i++) cin>>a[i],s[i]=s[i-1]+a[i];
	for(int i=1;i<=n;i++) cin>>b[i],ss[i]=ss[i-1]+b[i];
	LL ans1=0,ans2=1e18;
	int ans=0;
	for(int i=k;i<=n;i++)
	{
		LL temp1=s[i]-s[i-k];
		LL temp2=ss[i]-ss[i-k];
		if(temp1>ans1)
		{
			ans1=temp1,ans2=temp2;
			ans=i-k+1;
		}
		else if(temp1==ans1&&temp2<ans2)
		{
			ans2=temp2;
			ans=i-k+1;
		}
	}
	cout<<ans;
	return 0;
}

F: 红色和紫色【难度: 一般 / 知识点: 博弈论】


博弈论的题,不擅长,还好这个模型比较简单。
我们可以分析出,谁最后放谁就赢了。
故如果格子数是奇数,一号手赢,否则二号手赢。

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
long long int a,b;
int main(void)
{
	cin>>a>>b;
	if((a*b)&1) puts("akai");
	else puts("yukari");
	return 0;
}

H: 漂亮数 【难度: 一般 / 知识点: 线性筛 打表】

#include<bits/stdc++.h>
using namespace std;
const int N=1e8+10;
const int M=1e6*5+10;
int prime[M],cnt,st[N];
int s[N];
void f()
{
	int n=1e8;
	for(int i=2;i<=n;i++)
	{
		if(!st[i]) prime[cnt++]=i;
		for(int j=0;prime[j]<=n/i;j++)
		{
			st[prime[j]*i]=1;
			if(i%prime[j]==0) break;
		}
	}
	for(int i=0;prime[i]*prime[i]<=n;i++)
	{
		for(int j=i;prime[i]*prime[j]<=n;j++)
		{
			s[prime[i]*prime[j]]++;
		}
	}
	for(int i=1;i<=n;i++) s[i]+=s[i-1];// 前缀和
}
int main(void)
{
	int t; cin>>t;
	f();
	while(t--)
	{
		int l,r; scanf("%d%d",&l,&r);
		printf("%d\\n",s[r]-s[l-1]);
	}
	return 0;
}

I: 加减【难度: 中 / 知识点: 贪心 双指针 前缀和】



滑动窗口。

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5+10;
LL a[N],n,k;
LL s[N];
int ans=0;
int main(void) 
{
	cin>>n>>k;
	for(int i=1;i<=n;i++) cin>>a[i];
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
	for(int i=1,j=1;i<=n;i++)
	{
		LL temp=a[(i+j+1)/2];
        LL index=(i+j+1)/2;
		while(j<=n && (temp*(index-1-i+1)-(s[index-1]-s[i-1])+s[j]-s[index-1]-(j-index+1)*temp<=k) ) 
		{
			j++,temp=a[(j+i+1)/2];
            index=(i+j+1)/2;
		}
		ans=max(ans,j-i);
	}
	cout<<ans;
	return 0;
}

J: 喵【难度: 简单 / 知识点: 字符串】


题目保证了" nya " 一定在末尾 故直接删除后三个字符即可。

#include<bits/stdc++.h>
using namespace std;
int main(void)
{
	string s; getline(cin,s);
	while(s.find("nya")!=-1)
	{
		int t=s.find("nya");
		s=s.substr(0,t)+s.substr(t+3);
	}
	cout<<s<<endl;
	return 0;
}

以上是关于牛客小白月赛37部分题解的主要内容,如果未能解决你的问题,请参考以下文章

牛客小白月赛 68 题解

牛客小白月赛37 I 加减

牛客小白月赛37 I 加减

牛客小白月赛37 I 加减

牛客小白月赛#69(A-E)

牛客网小白月赛34题解