“蔚来杯“2022牛客暑期多校训练营5补题

K  Headphones

题意

一天,尼奥的家停电了。所以他和他的妹妹Yasa想从抽屉里拿一些耳机。在黑暗中,如果他们随机拿了一些耳机,而Yasa已经拿出了k副耳机。NIO要带多少副耳机才能保证比妹妹多拿几副,也就是k+1副耳机。假设抽屉里有N副耳机,每副都不一样。

思路

本题应该考虑最不理想的情况,他拿了n-k+1+k个耳机时,可以确保里边有1+k对耳机。

代码

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <deque>
#include <stdio.h>
#include <vector>
#include <map>
#include <iomanip>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
//#define int long long
using namespace std;
typedef long long ll;
int n,k;
int main()
{
	IOS;
	
	while(cin>>n>>k)
	{
		if(n-k>k)
		{
			cout<<(n-k+1+k)<<endl;
		}
		else
		{
			cout<<"-1"<<endl;
		}
	}
	
	
	return 0;
}

C  Bit Transmission

题意

有个01组成的字符串,对某些位置询问是否是1,询问3n次,有至多一次询问返回的答案是错误的,问这些询问结果能否唯一确定字符串。

思路

所有询问一共只能发生一次错误,因而在所有的询问中,0的数量大于1的数量的输出0,1的数量大于0的数量的输出1,0的数量等于1的数量的机器坏了,错误次数多于1的也是机器坏了。

代码

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <deque>
#include <stdio.h>
#include <vector>
#include <map>
#include <iomanip>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
//#define int long long
using namespace std;
typedef long long ll;
int a[100005][2];
string temp; 
int main()
{
	IOS;
	
	int n;
	int i,j,k;
	int t;
	int shu;
	char s[5];
	while(cin>>n)
	{
		temp="";
		memset(a,0,sizeof(a));
		t=3*n;
		while(t--)
		{
			cin>>shu>>s;
			if(s[0]=='Y')
			{
				a[shu][1]++;
			}
			else if(s[0]=='N')
			{
				a[shu][0]++;
			}
		}
		
		int cuo=0;
		for(i=0;i<n;i++)
		{
			if(cuo>1)
				break;
			if(a[i][0]>a[i][1])
			{
				temp+='0';	
				cuo+=a[i][1];			
			}
			else if(a[i][0]<a[i][1])
			{
				temp+='1';
				cuo+=a[i][0];
			}
			else if(a[i][0]==a[i][1])
				break;
		}
		if(i!=n)
			cout<<"-1\n";
		else
			cout<<temp<<endl;
	}
	
	
	
	
	return 0;
}

H  Cutting Papers

题意

NIO和他四岁的小妹妹Yasa正在剪纸。NIO画了几条线段,得到一个封闭的区域,一个多边形,从一个数学不等式,∣x∣+∣y∣+∣x+y∣≤n。和Yasa画了一个圆,这个圆的中心与NIO画的多边形的中心重合,圆的半径是nn的一半。他们想切割出多边形和圆形的结合区域。假设他们玩基于无限纸的切割游戏。他们从纸上剪下的面积有多大?即求圆形和多边形的并集。

思路

将不等式转换为平面直角坐标系上的图形,再与圆取并集。

通过数学计算方法可得圆形于阴影部分的面积并集为(n/2)^2*(2+pi/2),因为本题精度有要求,pi取值应较为精细。可用acos(-1)来表示pi。

代码

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <deque>
#include <stdio.h>
#include <vector>
#include <map>
#include <iomanip>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define int long long
using namespace std;
typedef long long ll;
const double pi=acos(-1);
signed main()
{
	IOS;
	
	int n;
	while(cin>>n)
	{
		cout<<fixed<<setprecision(9)<<(n/2.0)*(n/2.0)*(2+pi/2.0)<<endl;
	}
	
	
	
	
	return 0;
}

G  KFC Crazy Thursday

题意

一天,尼奥在他的电脑上发现了一封来自他的朋友卡拉的电子邮件。他打开邮件,发现一张图片,上面有一大串26个小写字母。他问卡拉为什么给他寄这张照片。Kala说这是他给NIO的一个挑战:如果NIO能算出以“k”、“f”和“c”结尾的回文数,他会给NIO买一份肯德基套餐。聪明的NIO打开了一个人工智能软件,将图像上的所有字母转换成一个文本文件。NIO承诺,如果你能帮助他,他将与你分享肯德基套餐。

思路

采用manacher算法进行计算

代码

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <deque>
#include <stdio.h>
#include <vector>
#include <map>
#include <iomanip>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define int long long
using namespace std;
int numk[4000005]={0};
int numf[4000005]={0};
int numc[4000005]={0};
char s[4000005];
char s1[4000005];
int p[4000005];//p[i]记录s[i]能单侧延伸多长 
int manacher()
{
	int r=0;//最右边界 
	int c=0;//中心 
	int len=strlen(s);
	int ans=0;
	for(int i=1;i<len;i++)
	{
		if(i<r)
		{
			p[i]=min(r-i,p[2*c-i]);
			numk[i]+=numk[2*c-i];
			numf[i]+=numf[2*c-i];
			numc[i]+=numc[2*c-i];
			if(r-i<p[2*c-i])
			{
				for(int j=r-i;j<=p[2*c-i];j++)
				{
					if(s[2*c-i+j]==s[2*c-i-j])
					{
						if(s[2*c-i+j]=='k')
							numk[i]--;
						if(s[2*c-i+j]=='f')
							numf[i]--;
						if(s[2*c-i+j]=='c')
							numc[i]--;
					}
				}
			}
		}
		else
		{
			p[i]=1;
		}
		while(s[i+p[i]]==s[i-p[i]])
		{
            if(s[i+p[i]]=='k')
                numk[i]++; 
            if(s[i+p[i]]=='f')
                numf[i]++; 
            if(s[i+p[i]]=='c')
                numc[i]++; 
            p[i]++;
    	}
    	if(i+p[i]>r)
		{
            r=i+p[i];
            c=i;
        }
        ans=max(ans,p[i]);
	}
	return ans-1;
}
signed main()
{
	IOS;
	
	int n;
	cin>>n;
	int i,j,k;
	cin>>s1;
	j=0;
	//预处理 
	for(i=0;s1[i]!=0;i++)
	{
		s[++j]='#';
		s[++j]=s1[i];
	}
	s[0]='%';
	s[++j]='#';
	s[++j]=0;
	
	manacher();
	
	int sumk=0;
	int sumf=0;
	int sumc=0;
    for(i=0;i<=j;i++)
	{
        sumk+=numk[i];
        sumf+=numf[i];
        sumc+=numc[i];
        if(s[i]=='k') 
			sumk++;
        if(s[i]=='f')
			sumf++;
        if(s[i]=='c') 
			sumc++;
    }
	cout<<sumk<<" "<<sumf<<" "<<sumc<<endl;
	
	
	return 0;
}

B  Watches

题意

尼奥是这家钟表店的老板。一天,他想从工厂购买一批手表。然而,他住在一个征收重税的国家。如果他买了k个手表,他单子上的第一只手表就要花掉他(ai(原价)+k×i)美元(原列表中第i个)。现在NIO只有M美元,所以NIO问你他实际上可以购买多少块手表。

思路

采用二分的思想,在1到n上二分确定k的值,再对整体按k处理后进行排序,求得1到k的总价值是否在m以内,进而求出最后的合适的数量。

代码

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <deque>
#include <stdio.h>
#include <vector>
#include <map>
#include <iomanip>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define int long long
using namespace std;
struct node
{
	int val;
	int xu;
}pos[100005];
int n,m;
int mid;
bool cmp(node a,node b)
{
	return a.val+mid*a.xu<b.val+b.xu*mid;
}
bool check(int mid)
{
	int ans=0;
	sort(pos+1,pos+n+1,cmp);
	for(int i=1;i<=mid;i++)
	{
		ans+=pos[i].val+mid*pos[i].xu;
		if(ans>m)
			return false;
	}
	return true;
}
signed main()
{
	IOS;
	
	cin>>n>>m;
	int i,j,k;
	for(i=1;i<=n;i++)
	{
		cin>>pos[i].val;
		pos[i].xu=i;
	}
	int sum=0;
	int l=0;
	int r=n;
	while(l<r)
	{
		mid=(l+r+1)/2;
		if(check(mid))
			l=mid;
		else
			r=mid-1;
	}
	cout<<l<<endl;
	
	
	
	
	
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值