Dytechlab Cup 2022

俩礼拜没正儿八经打代码了

and 不要看见题目就暴力暴力的,多观察下数据(B痛苦的领悟)

Dashboard - Dytechlab Cup 2022 - Codeforces

A:给n本书,每本书用一个小写字母表示,k本一组(一定k为n的因数),求每组的mex值,并组合成字符串,使得字符串最大(不存在字母z)

贪心,每次从a选到第min(k,25)个字母,遇到0直接输出并跳出即可,都不为零就输出下一个字母

int _=read();
	while(_--)
	{
		memset(a,0,sizeof(a));
		char t;
		int n=read(),k=read();
		for(int i=1;i<=n;i++)
		{
			cin>>t;
			a[t-'a']++;
		}
		
		for(int i=1;i<=k;i++)
		{
			int cnt=-1;
			for(int j=0;j<n/k;j++)
			{
				if(a[j]==0)
				{
					cnt=j;
					break;
				}
				a[j]--;
			}
			if(cnt==-1) t='a'+n/k;
			else t='a'+cnt;
			cout<<t;
		}
		cout<<"\n";
	}

B:给l和r,求区间内有多少个数x满足\lfloor \sqrt{x} \rfloor是x的因数

我们枚举下可行的答案

1:1 2 3

2:4 6 8

3:3 12 15

4:16 20 24

5:25 30 35

……

看出规律了吗,每两个平方数之间可行解为2个

原因:求(a-1)^2a^2之间的可行解,就是求(a-1)\times k < a^2中k的最大值与a的大小的差

a^2-1=(a+1)\times(a-1)

因此k的最大值是a+1,a+1-(a-1)=2

得证

因此找出l与r的平方数,在判断一下前后多加/少加的数就ok了

int _=read();
	while(_--)
	{
		ll n=read(),m=read();
		ll k=sqrt(n),z=sqrt(m);
		ll ans=(z-k)*3;
		for(int i=k;i*(k)<(k+1)*(k+1);i++)
		{
			if(i*k>=n)ans++;
		}
		for(int i=z;i*(z)<(z+1)*(z+1);i++)
		{
			if(i*(z)>m)ans--;
		}
		printf("%lld\n",ans);
	}

C:棋盘上有三个棋子,呈L的形状,每颗棋子可以跳过其他棋子(横,纵,斜,类比孔明棋,但是不拿走),求有没有棋子能到目标点。

首先要确定的是,L的中心点延伸出来的十字的点是一定能到达的,因此我们需要找出中心点能转移的所有位置,其横纵轴都是能到达的

假设现在中心点为(x,y),其右上各一个点,如果将中心点横向转移,则可以通过右→左,上→左下,中→左,此时中心点转移到(x-2,y)同理可进行延伸,求出可行解图

有图可得,以任意三个符合条件的黄点出发(后会补充一种特殊情况),白点是无法到达的点,我们也可以尝试从白点反推是否符合条件,发现可转移到白点的点都是白点,成立。

因此与中心点横纵坐标的差值均为奇数的情况是无解,其余为有解

注意如果初始中心点在角上时,只能向其十字转移,需要特判

int _=read();
	while(_--)
	{
		ll n=read();
		ll a,b;
		ll a1=read(),b1=read(),a2=read(),b2=read(),a3=read(),b3=read();
		if(a1==a2)a=a1;
		if(a2==a3)a=a2;
		if(a3==a1)a=a1;
		if(b1==b2)b=b1;
		if(b2==b3)b=b2;
		if(b3==b1)b=b1;
		ll x=read(),y=read();
		if((a==1||a==n)&&(b==1||b==n))
		{
			if(x==a||y==b) printf("YES\n");
			else printf("NO\n");
			continue;
		}
		if(abs(x-a)%2!=0&&abs(y-b)%2!=0) printf("NO\n");
		else printf("YES\n");
		//for(int i=1;i<=n;i++)
	}

后面暂时先不补了,先做作业QWQ

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值