可达鸭2023暑期打卡题解(CSP-X)

可达鸭【2023暑期编码之星打卡活动】CSP-X

求完数

完数:如果一个数等于不含它本身的其他因子之和,则称该数为‘完数’。如6的因子有1,2,3,6,且1+2+3= 6,因此6是完数。

题目描述:

输入一个正整数N(0 < N < 10000),输出小于N的所有完数及小于N的完数个数,个数前加 ‘*’ 。

输入:

输入一个正整数N(0 < N < 10000)

输出:

输出小于N的所有完数及小于N的完数个数。

样例:

//input
100
//output
6
28
*2

解题思路:

因为题目中规定 N N N小于10000,可以打出一个极其简单,人尽皆知的完全数表 6 , 28 , 496 , 8128 6,28,496,8128 6284968128
然后就可以计数输出了。

AC代码

#include<bits/stdc++.h>
using namespace std;
int a[4]={6,28,496,8128};
int sum=0;
int main()
{
	int N;
	cin>>N;
	for(int i=0;i<=3;i++)
	{
		if(a[i]<N)
		{
			cout<<a[i]<<endl;
			sum++;
		}
	}
	cout<<'*'<<sum<<endl;
	return 0;
}

字符串操作

题目描述:

有一个字符串,需要你完成以下几个操作:

1.删除所有元音字母
2.每个非元音字母前面加一个点
3.所有非元音大写字母转成小写字母

元音字母包含:A E I O U Y。

输入描述:

输入为只包含字母的字符串。字符串长度不超过100000。

输出描述:

输出经过处理后的字符串。

样例:

//input
aououR
//output
.r
//input
yeiouAEIOU
//output

//这组输出不包含任何字符

解题思路:

先将字符串输入,然后找既不是大写元音字母也不是小写元音字母(即大小写辅音字母),然后如果当前字符是大写就用 + 32 +32 +32的方法转成小写。
进行 p r i n t f ( ) printf() printf()输出,在每个字符前加一个点。

AC代码:

#include<bits/stdc++.h>
using namespace std;
int main()
{
	char a[100005];
	int i=0;
	scanf("%s",a);
	while(a[i])
	{
		if(!(a[i]=='A'||a[i]=='E'||a[i]=='I'||a[i]=='O'||a[i]=='U'||a[i]=='Y'||a[i]=='a'||a[i]=='e'||a[i]=='i'||a[i]=='o'||a[i]=='u'||a[i]=='y'))
		{
			if(a[i]<='Z'&&a[i]>='A')
			{
				printf(".%c",a[i]+32);
			}
			else printf(".%c",a[i]);
		}
		i++;
	}
	return 0;
}

求素数(个位数为7)

题目描述

给出一个正整数N,计算出7到N之间个位数为7的素数有多少个。
例如:7到20之间的素数有7、11、13、17、19,其中个位为7的有2个,分别为7和17。

输入描述

输入一个正整数 N ( 10 < N < 9999 ) N(10 < N < 9999) N(10<N<9999)

输出描述

输出7到 N N N(包含7和 N N N)之间个位数为7的素数有多少个。

样例

//input
20
//output
2

解题思路

设一整型变量 s u m sum sum表示个数,设为0。
先编写一个 b o o l bool bool型函数 i s P r i m e isPrime isPrime判断一个数是不是是素数,是返回 1 1 1,不是返回 0 0 0
在主函数中枚举 1 − N 1-N 1N的数,如果这个数满足:

  • 模10的结果为7
  • 函数 i s P r i m e isPrime isPrime判断为真

就让 s u m sum sum加1。
直到循环结束,输出 s u m sum sum就是最终的答案了。

AC代码

#include<bits/stdc++.h>
using namespace std;
bool isPrime(int x)
{
	for(int i=2;i<=sqrt(x);i++)
	{
		if(x%i==0)
		{
			return false;
		}
	}
	return true;
}
int main()
{
	int n;
	int sum=0;
	cin>>n;
	for(int s=1;s<=n;s++)
	{
		if(s%10==7&&isPrime(s)==1)
		{
			sum++;
		}
	}
	cout<<sum;
	return 0;
}

超市福利

题目描述

兴隆超市在搞促销。
在超市买矿泉水后,可以用 k k k个空矿泉水瓶换一瓶新的矿泉水,一开始,小可买了 n n n瓶矿泉水。
如果喝掉了水瓶中的水,那么水瓶就会变成空的。
给定两个正整数, n n n k k k,请计算下小可最多可以喝到多少瓶农夫山泉矿泉水?

输入描述

输入包含两个正整数 n n n k k k ,分别表示小可所买的矿泉水的瓶数、兑换一瓶矿泉水需要的空瓶个数。

输出描述

输出一行,表示小可最多可以喝到的矿泉水瓶数。

解题思路

初始的水会变成空瓶,空瓶数除以 k k k又得到了水,如果有余数就留着凑空瓶。
因此我们可以有以下想法:

  • a n s ans ans为总喝水数, k p kp kp为空瓶数, n n n为现在这一次换水所得的水。
  • 只要 n n n大于0,则:
  • a n s ans ans应包含所有水瓶数,加上 n n n
  • 喝完 n n n瓶水有 n n n个空瓶,所以 k p kp kp也加上 n n n
  • 新一次换水可得水数应为空瓶数除以 k k k n n n等于 k p / k kp/k kp/k
  • 可能会剩下一些空瓶, k p kp kp取模 k k k存储这些空瓶。
  • 最后输出 a n s ans ans即可。

AC代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n,k;
	cin>>n>>k;
	int ans=0,kp=0;
	while(n>0)
	{
		ans+=n;
		kp+=n;
		n=kp/k;
		kp%=k;
	}
	cout<<ans;
	return 0;
}

比较字符串

题目描述

许多正在完成StUDY(矮人州立大学)学士学位课程的矮人得知,“没有genome,是没有学位的”。这意味着所有矮人都应该撰写关于基因组的论文。矮人基因组并不简单。它由包含小写拉丁字母的字符串组成。

矮人米莎(Dwarf Misha)已经选好了论文主题:通过两个矮人基因组来确定它们是否属于同一种族。如果我们可以在第一个矮人的基因组中通过交换两个字符得到第二个矮人的基因组,那么两个矮人就属于同一个种族。帮助矮人米莎(Dwarf Misha)找出两个矮人是否属于同一种族。

简要题面

求两个只含小写字母的字符串是否满足:

  • 两个字符串含有的字符种类和每个字母的个数均相同。
  • 例如acc和cca均含有两个c,一个a,因此这组字符串满足上述要求。

输入格式

第一行包含第一个矮人的基因组:一个非空字符串,由小写字母组成。

第二行包含第二个矮人的基因组:一个非空字符串,由小写字母组成。

每个基因组中的字母数不超过 1 0 5 10^5 105。保证对应于基因组的字符串是不同的。

给定的基因组可能具有不同的长度

样例

//input
abccdfg
ccdabgf
//output
YES

输出格式

如果矮人属于同一种族,则输出 “YES”。否则,输出“NO”。

解题思路

首先设两字符串为 a a a b b b,长度分别为 l e n 1 len1 len1 l e n 2 len2 len2
遍历字符串 a a a,使用 f i n d find find函数查找当前这个字符在 b b b中的位置。

  • 如果 f i n d find find函数返回了-1,直接输出 N O NO NO,结束程序。
  • 否则,将这个位置上的字符从 b b b中删除,再查找下一个。

如果循环结束,输出 Y E S YES YES
由于字符串最多只有 100000 100000 100000个字符,所以这个暴力算法完全可行。

然后!!!
题目中说,两个基因组可能有不同长度。
所以 l e n 1 len1 len1 l e n 2 len2 len2不同的情况下直接输出 N O NO NO就可以了。

AC代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
	string a;
	string b;
	cin>>a>>b;
	int idx=-1;
	int len1=a.length();
	int len2=b.length();
	if(len1!=len2)
	{
		cout<<"NO";
		return 0;
	}
	for(int i=0;i<len1;i++)
	{
		idx=b.find(a[i]);
		if(idx==-1)
		{
			cout<<"NO";
			return 0;
		}
		b.erase(idx,1);
	}
	if(idx!=-1)cout<<"YES";
	return 0;
}

乡村Vitya

题目描述

每年夏天,Vitya都会去乡下探望奶奶。今年夏天,他得了一种病。乡下奶奶们都知道月亮落下时应该可以治疗这种病。所以,Vitya必须赶上月亮落下的那一刻。

月球周期持续30天。每天月亮可见部分的大小(以Vitya的单位)是
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1。
然后循环重复,因此第二个1之后再次变为0。

由于乡下没有互联网,Vitya连续n天观察月亮,并且记录下这些天中每天月亮可见部分的大小。请帮助他找出月亮在接下来一天是升还是降,或者不确定。

输入描述

输入的第一行包含一个整数n(1≤n≤92)——表示Vitya连续观察月亮可见部分大小的总天数。

第二行包含n个整数 a i a_i ai(0≤ a i a_i ai≤15)——Vitya记录每天月亮可见部分的大小。

确保输入数据是一致的。

输出描述

如果Vitya可以确定,第n+1天时月球可见部分的大小比第n天小,输出“DOWN”;如果他确定月亮可见部分的大小会增加,输出“UP”。如果无法确定月球究竟会发生什么,请输出-1。

样例

//input
5 
3 4 5 6 7
//output
UP
//input
5
9 8 7 6 5
//output
DOWN
//input
5
1 1 1 1 1
//output
-1

解题思路

这道题实际上就是要输入一串数字,然后求倒数第一个和倒数第二个谁大谁小。
所以就可以判断并输出了。

  • 判断一:若输入的 n n n为1且 a n a_n an不为0也不为15,直接输出-1结束程序。
  • 判断二:若输入的 a n a_n an为15,下一个月相必为0,下降,输出 D O W N DOWN DOWN结束程序。
  • 判断三:若输入的 a n a_n an为0,下一个月相必为15,上升,输出 U P UP UP结束程序。
  • 判断四:若不满足前三条,且倒数第二个月相比倒数第一个月相大,说明月亮在下降,输出 D O W N DOWN DOWN结束程序。
  • 判断五:若不满足前三条,且倒数第二个月相比倒数第一个月相小,说明月亮在上升,输出 U P UP UP结束程序。
  • 判断六:若出现完全相等的情况,输出-1结束程序。

AC代码

#include<bits/stdc++.h>
using namespace std;
int n;
int a[100];
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	if(n==1)
	{
		if(a[1]!=0&&a[1]!=15)
		{
			cout<<-1;
			return 0;
		}
	}
	if(a[n]==15)
	{
		cout<<"DOWN";
		return 0;
	}
	else if(a[n]==0)
	{
		cout<<"UP";
		return 0;
	}
	else
	{
		if(a[n]>a[n-1])
		{
			cout<<"UP";
			return 0;
		}
		else if(a[n]<a[n-1])
		{
			cout<<"DOWN";
			return 0;
		}
	}
	cout<<"-1";
	return 0;
}

统计成绩

题目描述

n位同学参加了期中考试,考试共有 m 门课程。
考试结束之后,老师想知道:每位同学有几门课程达到或超过了课程的班级平均分?
现在,请你帮忙统计一下 。

输入描述

n位同学参加了期中考试,考试共有 m 门课程。
考试结束之后,老师想知道:每位同学有几门课程达到或超过了课程的班级平均分?
现在,请你帮忙统计一下 。

输出描述

共 n 行,每行一个整数,表示该同学达到或超过平均分的课程数量。

样例

//input
5 3
81 80 86
55 74 79
92 47 99
50 65 41
42 61 74
//output
3
2
2
0
0

样例解释

三门课程平均分为 64 64 64 65.4 65.4 65.4 75.8 75.8 75.8

  • 第一个同学三门全部超过平均分。
  • 第二个同学第二门,第三门超过平均分。
  • 第三个同学第一门,第三门超过平均分。
  • 第四个同学全部低于平均分。
  • 第五个同学也全部低于平均分。

所以输出为 3 , 2 , 2 , 0 , 0 3,2,2,0,0 3,2,2,0,0

解题思路

首先,把输入的成绩用二维数组保存( n ∗ m n*m nm),每科的平均成绩用一维数组保存(有 m m m项)。

第一步(求平均成绩),遍历从 1 1 1 m m m(列数),用 s u m sum sum累加求和,然后把这一科的平均值保存在一维数组中(强制类型转换为 d o u b l e double double)。

第二步(求达标个数),定义 a n s ans ans变量初始值为0,用来存答案。
先一重循环遍历每一个学生,在一重循环遍历这个学生每门课的成绩,如果比这门课的平均成绩要高, a n s ans ans就加一,循环过后直接输出,再遍历下一名学生。

小贴士:每输出完一名学生的达标科目数, a n s ans ans一定要置零。

AC代码

#include<bits/stdc++.h>
using namespace std;
int n,m;
int score[105][25];
double ave[25];
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>score[i][j];
		}
	}
	int sum;
	for(int i=1;i<=m;i++)
	{
		sum=0;
		for(int j=1;j<=n;j++)
		{
			sum+=score[j][i];
		}
		ave[i]=(double)sum/n;
	}
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		ans=0;
		for(int j=1;j<=m;j++)
		{
			if(score[i][j]>=ave[j])
			{
				ans++;
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值