CSP-M4

TT数鸭子

题目描述

这一天,TT因为疫情在家憋得难受,在云吸猫一小时后,TT决定去附近自家的山头游玩。
TT来到一个小湖边,看到了许多在湖边嬉戏的鸭子,TT顿生羡慕。此时他发现每一只鸭子都不
一样,或羽毛不同,或性格不同。TT在脑子里开了一个map<鸭子,整数> tong,把鸭子变成了
一些数字。现在他好奇,有多少只鸭子映射成的数的数位中不同的数字个数小于k。

输入描述

输入第一行包含两个数n,k,表示鸭子的个数和题目要求的k。
接下来一行有n个数, a i a_i ai,每个数表示鸭子被TT映射之后的值。

输出描述

输出一行,一个数,表示满足题目描述的鸭子的个数。
无行末空格

样例输入

6 5
123456789 9876543210 233 666 1 114514

样例输出

4

数据组成
数据点
n k a i a_i ai
1 n<=1000 k=10 1 0 6 10^6 106
2 n<=1000 k=1 1 0 6 10^6 106
3,4,5 n<= 1 0 5 10^5 105 k<=100 1 0 9 10^9 109
6,7,8,9,10 n<= 1 0 6 10^6 106 k<= 1 0 6 10^6 106 $10^{15}

做法

记录每个数不同数位的个数,判断是否符合条件。
把cin换成scanf就不超时了。。。然鹅出错,发现是>=和>的问题,需要注意临界值、小于和不大于。

代码

#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;

long long a;

int main()
{
	int n,k;
	//cin>>n>>k;
	scanf("%d %d",&n,&k);
	if(k<=1||k>10)
	{
		for(int i=0;i<n;i++)
		{
			scanf("%lld",&a);
		}
		if(k<=1)
		{
			cout<<0<<endl;
		}
		else
		{
			cout<<n<<endl;
		}
	}
	else
	{
		int m[16];
		int ans=0;
		for(int i=0;i<n;i++)
		{
			memset(m,0,sizeof(m));
			scanf("%lld",&a);
			int temp=0;
			int num=0;
			while(a)
			{
				temp=a%10;
				a=a/10;
				if(m[temp]==0)
				{
					m[temp]=1;
					num++;
					if(num>=k)
				    break;
				}
			}
			if(num<k)
			ans++;
		}
		cout<<ans<<endl;
	}
	return 0;
}

ZJM要抵御宇宙射线

题目描述

据传,2020年是宇宙射线集中爆发的一年,这和神秘的宇宙狗脱不了干系!但是瑞神和东东忙
于正面对决宇宙狗,宇宙射线的抵御工作就落到了ZJM的身上。假设宇宙射线的发射点位于一个
平面,ZJM已经通过特殊手段获取了所有宇宙射线的发射点,他们的坐标都是整数。而ZJM要构
造一个保护罩,这个保护罩是一个圆形,中心位于一个宇宙射线的发射点上。同时,因为大部分
经费都拨给了瑞神,所以ZJM要节省经费,做一个最小面积的保护罩。当ZJM决定好之后,东东
来找ZJM一起对抗宇宙狗去了,所以ZJM把问题扔给了你~

输入描述

输入 第一行一个正整数N,表示宇宙射线发射点的个数
接下来N行,每行两个整数X,Y,表示宇宙射线发射点的位置

输出描述

输出包括两行
第一行输出保护罩的中心坐标x,y 用空格隔开
第二行输出保护罩半径的平方
(所有输出保留两位小数,如有多解,输出x较小的点,如扔有多解,输入y较小的点)
无行末空格

样例输入

5
0 0
0 1
1 0
0 -1
-1 0

样例输出

0.00 0.00
1.00

数据组成
数据点 n x y
1~5 n<=100 |x|<=10000 |y|<=10000
6~10 n<=1000 |x|<=100000 |y|<=100000

做法

遍历每个坐标,寻找符合题意的半径最小值,以及中心坐标。
把初始化的半径最小值minn调大一位数就可以AC了(1e10是11位数)。。。

代码

#include<iostream> 
using namespace std;

struct coo
{
	long long x;
	long long y;
}a[1099],ans,t;

int main()
{
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
	{
		cin>>a[i].x>>a[i].y;
	}
	long long minn=99999999999;
	for(int i=0;i<n;i++)
	{
		long long d=0;
		long long maxx=0;
		t.x=a[i].x;
		t.y=a[i].y;
		for(int j=0;j<n;j++)
		{
			d=(a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y);
			if(d>maxx)
			{
				maxx=d;
			}
		}
		if(maxx<minn)
		{
			minn=maxx;
			ans.x=t.x;
			ans.y=t.y;
		}
		else if(maxx==minn)
		{
			if(ans.x>t.x)
			{
				ans.x=t.x;
				ans.y=t.y;
			}
			else if(ans.x==t.x&&ans.y>t.y)
			{
				ans.x=t.x;
				ans.y=t.y;
			}
		}
	}
	cout<<ans.x<<'.'<<0<<0<<' '<<ans.y<<'.'<<0<<0<<endl;
	cout<<minn<<'.'<<0<<0;
	return 0;
}

宇宙狗的危机

时间限制 空间限制
5S 256MB

题目描述

在瑞神大战宇宙射线中我们了解到了宇宙狗的厉害之处,虽然宇宙狗凶神恶煞,但是宇宙狗有一
个很可爱的女朋友。
最近,他的女朋友得到了一些数,同时,她还很喜欢树,所以她打算把得到的数拼成一颗树。
这一天,她快拼完了,同时她和好友相约假期出去玩。贪吃的宇宙狗不小心把树的树枝都吃掉
了。所以恐惧包围了宇宙狗,他现在要恢复整棵树,但是它只知道这棵树是一颗二叉搜索树,同
时任意树边相连的两个节点的gcd(greatest common divisor)都超过1。
但是宇宙狗只会发射宇宙射线,他来请求你的帮助,问你能否帮他解决这个问题。
补充知识:
GCD:最大公约数,两个或多个整数共有约数中最大的一个 ,例如8和6的最大公约数是2。
一个简短的用辗转相除法求gcd的例子:
int gcd(int a,int b){return b == 0 ? a : gcd(b,a%b);}

输入描述

输入第一行一个t,表示数据组数。
对于每组数据,第一行输入一个n,表示数的个数
接下来一行有n个数 a i a_i ai,输入保证是升序的。

输出描述

每组数据输出一行,如果能够造出来满足题目描述的树,输出Yes,否则输出No。
无行末空格。

样例输入1

1
6
3 6 9 18 36 108

样例输出1

Yes

样例输入2

2
2
7 17
9
4 8 10 12 15 18 33 44 81

样例输出2

No
Yes

样例解释

样例1可构造如下图
在这里插入图片描述

数据组成
给出的数为上限。
数据点数 t n a i a_i ai
1,2,3 5 15 1 0 9 10^9 109
4,5,6 5 35 1 0 9 10^9 109
7,8,9,10 5 700 1 0 9 10^9 109

做法

动态规划
二叉搜索树的左右子树也是二叉搜索树,于是可以用l[i][j]表示[i,j-1]为j的左子树,r[i][j]表示[i+1,j]为i的右子树。当左子树或右子树为空时,也可以构成二叉搜索树,即l[i][i]=1;r[i][i]=1;用数组dp记录i,j的最大公约数是否大于1.

转移方程为:

if(dp[j-1][k]==1)	r[j-1][i+j-1]=1;
if(dp[k][i+j]==1)   l[i+j][j]=1;

当1-n可以连成二叉搜索树时,就可以构造一棵树。

代码

#include<iostream>
#include<string.h>
using namespace std;

int l[709][709];
int r[709][709];
int dp[709][709];
int a[709];

int gcd(int a,int b){return b == 0 ? a : gcd(b,a%b);}

int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n;
		cin>>n;
		memset(l,0,sizeof(l));
		memset(r,0,sizeof(r));
		memset(a,0,sizeof(a));
		memset(dp,0,sizeof(dp));
		for(int i=1;i<=n;i++)
		{
			cin>>a[i];
		}
		for(int i=1;i<=n;i++)
		{
			for(int j=i;j<=n;j++)
			{
				if(gcd(a[i],a[j])>1)
				{
					dp[i][j]=1;
					dp[j][i]=1;
				}
			}
			l[i][i]=1;
			r[i][i]=1;
		}
		bool b=false;
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n-i+1;j++)
			{
				for(int k=1;k<=i+j-1;k++)
				{
					if(l[k][j]&&r[k][i+j-1])
					{
						if(i==n)
						{
							b=true;
							break;
						}
						if(dp[j-1][k]==1)
						{
							r[j-1][i+j-1]=1;
						}
						if(dp[k][i+j]==1)
						{
							l[i+j][j]=1;
						}
					}
				}
				if(b)
				break;
			}
			if(b)
			break;
		}
		if(b)
		cout<<"Yes"<<endl;
		else
		cout<<"No"<<endl; 
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于计算机专业的学生而言,参加各类比赛能够带来多方面的益处,具体包括但不限于以下几点: 技能提升: 参与比赛促使学生深入学习和掌握计算机领域的专业知识与技能,如编程语言、算法设计、软件工程、网络安全等。 比赛通常涉及实际问题的解决,有助于将理论知识应用于实践中,增强问题解决能力。 实践经验: 大多数比赛都要求参赛者设计并实现解决方案,这提供了宝贵的动手操作机会,有助于积累项目经验。 实践经验对于计算机专业的学生尤为重要,因为雇主往往更青睐有实际项目背景的候选人。 团队合作: 许多比赛鼓励团队协作,这有助于培养学生的团队精神、沟通技巧和领导能力。 团队合作还能促进学生之间的知识共享和思维碰撞,有助于形成更全面的解决方案。 职业发展: 获奖经历可以显著增强简历的吸引力,为求职或继续深造提供有力支持。 某些比赛可能直接与企业合作,提供实习、工作机会或奖学金,为学生的职业生涯打开更多门路。 网络拓展: 比赛是结识同行业人才的好机会,可以帮助学生建立行业联系,这对于未来的职业发展非常重要。 奖金与荣誉: 许多比赛提供奖金或奖品,这不仅能给予学生经济上的奖励,还能增强其成就感和自信心。 荣誉证书或奖状可以证明学生的成就,对个人品牌建设有积极作用。 创新与研究: 参加比赛可以激发学生的创新思维,推动科研项目的开展,有时甚至能促成学术论文的发表。 个人成长: 在准备和参加比赛的过程中,学生将面临压力与挑战,这有助于培养良好的心理素质和抗压能力。 自我挑战和克服困难的经历对个人成长有着深远的影响。 综上所述,参加计算机领域的比赛对于学生来说是一个全面发展的平台,不仅可以提升专业技能,还能增强团队协作、沟通、解决问题的能力,并为未来的职业生涯奠定坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值