CSU-2022期中机试

这是我的第一篇博客,欢迎大家给予建议。

前言

1.卡牌排序(20分)

2.小南找书(20分)

3.时钟加法(20分)

4.地铁出行(20分)

5.出线概率(10分)

6.填数游戏(10分)

总结


前言

对于2022C语言的期中机试,总体来说难度不大,但较往年而言难度还是加大了些。如有错误和更好解法,欢迎批评指正。


提示:以下是本篇文章正文内容

1.卡牌排序(20分)

题目描述

小南有一个习惯,他喜欢将所有卡牌按照牌面数字的奇偶性分类并由小到大排序好,由于他最近实验课非常多,他想让优秀的你帮帮他。

输入

多个样例。每个样例包含2行输入: 

第1行输入一个正整数n(2≤n≤10000)表示卡牌数的张数,第2行输入n个正整数ai (ai 满足int类型范围)表示卡牌牌面上的数字,奇数和偶数的个数大于等于1。

输出

每个样例输出2行,第1行是由小到大排序好的奇数数字卡牌,第2行是由小到大排序好的偶数数字卡牌,数字之间用1个空格分开。每两个样例的输出结果之间用1个空行分开。

样例输入 Copy

5
1 6 9 7 2
2
6 101

样例输出 Copy

1 7 9
2 6

101
6 

代码如下(示例):

#include<stdio.h>
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		int a[10000];
		int i,j,m,t,x;
		for(i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
	}
		for (i = 0; i < n - 1; i++) {
		for (j = i + 1; j > 0; j--) {
			if (a[j] < a[j - 1]) {
				a[j] = a[j] + a[j - 1];
				a[j - 1] = a[j] - a[j - 1];
				a[j] = a[j] - a[j - 1];
			} else
				break;
		}
	}
	for (i = 0; i < n; i++)
	{
		if(a[i]%2!=0)
		printf("%d ",a[i]);
	}
	printf("\n");
	for (i = 0; i < n; i++)
	{
		if(a[i]%2==0)
		printf("%d ",a[i]);
	}
	printf("\n");
	printf("\n");
	}
	return 0;
}

2.小南找书(20分)

题目描述

小南热心志愿者活动,有时间的时候会在图书馆帮忙整理书籍。图书馆有一个很大的书架,书架一共有n(1≤n≤103)层,第i层上放了ai (1 ≤ ai ≤ 103)本书。每本书用连续的数字进行了编号:第1层书架上的书从1号到a1号,第2层放的书是从a1+1号到a1 + a2号,以此类推。

例如:当n等于2,a1为1,a2为3时,第1层书架上的1本书编号为1,第2层书架上的3本书编号依次为2、3、4。

小南想让你帮他编程实现,对于给定的书的编号,快速找到这本书在书架的第几层上。

说明:数组定义时如果长度大于106,有些编译器需要定为外部变量。

输入

多个样例。 每个样例输入包括4行:

第1行输入一个整数n (1≤n≤ 103),代表书架的层数。

第2行输入n个整数a1, a2, ..., an (1≤ai ≤103,a1+a2+...+ an ≤106),其中ai代表第i层书架上的书的数量。

第3行输入一个整数m (1≤m≤103)代表小南要找的书的数量。

        第4行输入m个整数b1, b2, ...,bm(1 ≤ ba1+a2+...+ an),分别表示小南要找的m本书的编号。

输出

每个样例输出m行,第i行包含一个整数,代表编号为 bi的书所在的书架的层数。

样例输入 Copy

2
1 3
2
1 3
5
1 8 3 5 8
3
1 24 11

样例输出 Copy

1
2
1
5
3

代码如下(示例):

#include<stdio.h>
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		int i,m,j;
		int a[1001]={0};
		int b[1001]={0};
		int sum=0;
		for(i=0;i<n;i++)
		{
			scanf("%d",&a[i]);
		}
		scanf("%d",&m);
		for(j=0;j<m;j++)
		{
			scanf("%d",&b[j]);
				for(i=0;i<n;i++)
			{
				sum+=a[i];
				if(b[j]<=sum)
			{
		    	printf("%d\n",i+1);
		    	sum=0;
				break;
			}
			}
		}
		}
	return 0;
}

3.时钟加法(20分)

题目描述

小南最近迷上了各种形式的加法,例如时钟加法,时钟加法是指给定一个当前时间,其形式为h:m:s,计算加上n秒后新的时间。你能帮他编程实现吗?

输入

多个样例。每个样例输入1行形式为h:m:s+n的数据,其中h(0≤h≤23)代表小时,m(0≤m≤59)代表分钟,s(0≤s≤59)代表秒钟,n(1≤n≤105)代表经过的秒数。

输出

每个样例输出新的时间,形式为h:m:s。每个样例输出结果占一行。

样例输入 Copy

0:0:0+360
23:29:59+1801
7:8:15+1

样例输出 Copy

00:06:00
00:00:00
07:08:16

代码如下(示例):

#include<stdio.h>
int main()
{
	int h,m,s;
	long long int n=0;
		int sum=0;
		int cnt=0;
		int shi,fen,miao;
	while(scanf("%d:%d:%d+%lld",&h,&m,&s,&n)!=EOF)
	{
		sum=h*3600+m*60+s;
		cnt=sum+n;
		shi=cnt/3600;
		fen=(cnt-shi*3600)/60;
		miao=cnt-shi*3600-fen*60;
		while(shi>=24)
	     shi=shi-24;
	    if(miao==60)
	    fen++;
	    if(fen==60)
	    shi++;
		printf("%02d:%02d:%02d\n",shi,fen,miao);
	}
	return 0;
}

4.地铁出行(20分)

题目描述

长沙地铁票有两种优惠方式,一种是月票,价格为100元;一种是消费打折,打折的规则为:本次乘车前总消费不足 10 元本次不打折,满 10 元不足 15 元本次打8 折,满 15 元不足 40 元本次打 5 折,已满 40 元后本次不打折。

例如:小南11月份乘坐了3次地铁,原价分别是10元、8元、2元,则第1次由于前面的消费为0元,因此不打折,小南花费10元;第2次的时候由于前面消费满了10元,因此8元的原票价打8折,即花费6.4元;第3次消费的时候前面累计消费了16.4元,因此2元的原票价打5折,即花费1元。那么小南11月份的实际地铁出行费用是17.4元。

        小南在2022年买的是地铁月票,已知小南某月出行的次数和每次出行的原票价,请问他购买月票的决定是否正确?即消费打折后的实际地铁出行费用大于等于月票价格,则认定为正确,否则认定为不正确。

输入

多个样例。 每个样例输入包含2行:

        第1行一个整数n(1≤n≤100)代表小南某月出行的次数,第2行 n 个正整数ai (1 ≤ ai ≤ 50)代表每次出行的原票价,小南是按照输入顺序依次出行的。

输出

对于每个样例,如果小南购买月票的决定正确就输出Yes,否则输出No。每个样例结果输出占一行。

样例输入 Copy

3
10 8 2
8
10 10 10 20 20 20 20 20

样例输出 Copy

No
Yes

代码如下(示例):

#include<stdio.h>
int main()
{
	int T;
	while(scanf("%d",&T)!=EOF)
	{
		double a[105];
		int i;
		double sum=0;
		for(i=0;i<T;i++)
		{
			scanf("%lf",&a[i]);	
			if(sum<10)
			sum+=a[i];
			else if(sum>=10 && sum<15 && i>=1)//i=1加不加都行
			sum+=a[i]*0.8;
			else if(sum>=15 && sum<40 && i>=1)
			sum+=a[i]*0.5;
			else
			sum+=a[i];
		}
		if(sum>=100)
		printf("Yes\n");
		else
		printf("No\n");
	}
	return 0;
}

5.出线概率(10分)

题目描述

2022世界杯正在火热进行中,小南是足球球迷,想知道某个球队的出线概率。经过严肃认真的研究,他发现其出线概率是一种可以计算的玄学:根据球队的名字可以得到出线概率!球队的名字由n(1≤n≤30)个小写字母c1, c2, ..., cn组成,小写字母只包括'a'~'i',其编号分别对应1~9,则出线概率的计算公式为:

 ((-1)1*(c1对应的编号)*101 +(-1)2*(c2对应的编号)*102 + ... (-1)n*(cn对应的编号)*10n )/10n+1

最终结果保留到小数点后n位。例如当球队名字为fff时,f字母对应的编号是6,则出线概率为:(-60+600-6000)/10000=-0.546。

给定某个球队的名字,请你帮助小南计算一下该球队出现在下次世界杯的概率吧!注意有些球队的名字组成很长哦,最大可达30位呢。

输入

多个样例。每个样例输入1行包含一个由小写字母组成的字符串(小写字母只包括'a'~'i'),表示球队的名字,长度为n(1≤n≤30)。

输出

每个样例输出一个实数表示出线概率,保留到小数点后n位。

样例输入 Copy

fff
aaaa

样例输出 Copy

-0.546
0.0909

代码如下(示例):

#include <stdio.h>
#include <string.h>
int main() {
	char sen[36];
	while (scanf("%s", sen) != EOF) {
		int length = strlen(sen);
		char ans1[length + 2];
		char ans2[length + 2];
		int r1 = 0, r2 = 0;
		for (int i = 0; sen[i] != 0; i++) {
			if (i % 2 == 0) {
				ans1[r1++] = sen[i] - 'a' + '1';
				ans2[r2++] = '0';
			} else {
				ans1[r1++] = '0';
				ans2[r2++] = sen[i] - 'a' + '1';
			}
		}
		ans1[r1++] = '\0';
		ans2[r2++] = '\0';
		char ans3[length + 5];
		int r3 = 0, temp = 0;
		if (length % 2 == 0) {
			for (int i = 0; ans1[i] != 0; i++) {
				if (ans2[i] - temp >= ans1[i]) {
					ans3[r3++] = '0' + (ans2[i] - '0' - ans1[i] + '0' - temp);
					temp = 0;
				} else {
					ans3[r3++] = '0' + (ans2[i] + 10 - '0' - ans1[i] + '0' - temp);
					temp++;
				}
			}
		} else {
			for (int i = 0; ans1[i] != 0; i++) {
				if (ans1[i] - temp >= ans2[i]) {
					ans3[r3++] = '0' + (ans1[i] - '0' - ans2[i] + '0' - temp);
					temp = 0;
				} else {
					ans3[r3++] = '0' + (ans1[i] + 10 - '0' - ans2[i] + '0' - temp);
					temp++;
				}
			}
		}
		ans3[r3] = '\0';
		if (length % 2 == 0)
			printf("0.");
		else
			printf("-0.");
		for (int i = r3 - 1; i >= 0; i--) {
			printf("%c", ans3[i]);
		}
		printf("\n");
	}
	return 0;
}
#include<stdio.h>//80%
#include<math.h>
#include<string.h>
int main()
{
	char n[35];
	while(scanf("%s",&n)!=EOF)
	{
		long double gai=0.0;
		long double gailv=0.0;
		int len,i;
		int bian=0;
		len=strlen(n);
		for(i=0;i<len;i++)
		{
			if(n[i]=='a')
			bian=1;
			else if(n[i]=='b')
			bian=2;
			else if(n[i]=='c')
			bian=3;
			else if(n[i]=='d')
			bian=4;
			else if(n[i]=='e')
			bian=5;
			else if(n[i]=='f')
			bian=6;
			else if(n[i]=='g')
			bian=7;
			else if(n[i]=='h')
			bian=8;
			else
			bian=9;
			gai+=pow(-1,i+1)*bian*pow(10,i+1);
		}
		gailv=(double)gai/pow(10,len+1);
		printf("%.*Lf\n",len,gailv);
}
	return 0;
}

6.填数游戏(10分)

题目描述

小南是个素数爱好者,设计了一种与素数有关的填数游戏。该游戏的要求是:输入一个长度为n(1≤n≤10000)的数字串(由数字1~9组成,没有数字0)和一个正整数m(1≤m≤4),将数字串从左边开始,每取m位数字构成一个整数保存起来,剩余的不够m位的也构成一个整数。接下来,他将这些整数ai 按照以下四种特性进行分类:

(1)1类:整数ai 是素数,素数是指除了1和本身外不能被其他数整除的正整数,2是最小的素数。

(2)2类:整数ai 组成的各位数字之和是素数,如整数11的数字之和为2,是素数,满足该条件。

(3)3类:整数ai 组成的各位数字中至少有一个是素数,如整数123中,有素数数字2,满足该条件。

(4)4类:不满足前3类的其他整数。

数据分类按照1类、2类、3类和4类的顺序进行。例如整数223虽然满足1类、2类和3类特性,按照顺序归入1类;25满足2类和3类特性,按照顺序归入2类。接下来小南将这4类整数分别填入一个k*k的方阵中,k为奇数,满足3≤k≤101。该方阵用星号“*”分割成上三角形、左三角形、下三角形和右三角形四个部分,上三角形填入1类整数、左三角形填入2类整数、右三角形填入3类整数、下三角形填入4类整数。填数的过程按照整数出现的顺序从上到下从左至右进行,如果填不满则填充数字0,每个数据输出占5位,右对齐,方阵k的选择要求所有数据都可以按照要求填入且填入的0的个数最少。

说明:当输入的n位数字串为123456789123456789,输入的m为2时,整数分割情况如下:

      1类整数:23、67、89

      2类整数:12、34、56

      3类整数:78、45

      4类整数:91

选定的k为5时的填充情况如图1所示,选定的k为7时的填充情况如图2所示。根据题目要求填入的0的个数最少,则图1是正确的结果。

现有给定的n位数字串和正整数m,请你帮助小南编程实现输出正确的填充结果。

输入

        多个样例。 每个样例输入一行包含一个n(1≤n≤10000)位数字串(由数字1~9组成,没有数字0)和正整数m(1≤n≤4) 。

输出

每个样例按照填充要求输出一个正确的方阵图。输出的整数和星号“*”的位数都是5位,右对齐。每两个样例的输出结果之间用一个空行分开。

样例输入 Copy

123456789123456789 2
1234567 1

样例输出 Copy

    *   23   67   89    *
   12    *    0    *   78
   34   56    *   45    0
    0    *   91    *    0
    *    0    0    0    *

    *    2    3    5    *
    0    *    7    *    0
    0    0    *    0    0
    0    *    1    *    0
    *    4    6    0    *

代码如下(示例):

#include <stdio.h>
#include <string.h>

int zhishu(int a) {
	if (a < 2)
		return 0;
	else if (a == 2)
		return 1;
	else {
		for (int i = 2; i < a; i++) {
			if (a % i == 0)
				return 0;
		}
	}
	return 1;
}

int panduan2(int a) {
	int sum = 0;
	while (a > 0) {
		sum = sum + a % 10;
		a /= 10;
	}
	if (zhishu(sum))
		return 1;
	else
		return 0;
}

int panduan3(int a) {
	while (a > 0) {
		int t = a % 10;
		a /= 10;
		if (zhishu(t) )
			return 1;
	}
	return 0;
}

int main() {
	char sen[10086];
	int m;
	while (scanf("%s %d", sen, &m) != EOF) {
		int length = strlen(sen);
		int num = length / m + 1;
		int ass[num + 5];
		int way = 0;
		int temp = 0;
		int r = 0;
		for (int i = 0; sen[i] != 0; i++) {
			if (way < m) {
				temp = temp * 10 + sen[i] - '0';
				way++;
			} else {
				i--;
				ass[r++] = temp;
				temp = 0;
				way = 0;
			}
		}
		if (way != 0) {
			ass[r++] = temp;

		}
		int ans1[r], ans2[r], ans3[r], ans4[r];
		int r1 = 0, r2 = 0, r3 = 0, r4 = 0;
		for (int i = 0; i < r; i++) {
			if ((zhishu(ass[i]))) {
				ans1[r1++] = ass[i];
			} else if (panduan2(ass[i])) {
				ans2[r2++] = ass[i];
			} else if (panduan3(ass[i])) {
				ans3[r3++] = ass[i];
			} else {
				ans4[r4++] = ass[i];
			}
		}
		int k = 3;
		int ling = 0;
		int max = r1 > r2 ? r1 : r2;
		max = max > r3 ? max : r3;
		max = max > r4 ? max : r4;
		for (k = 3; k <= 101; k++) {
			if (k % 2 == 0)
				continue;
			int all = k * k, left = all - k - k + 1;
			ling = left - r1 - r2 - r3 - r4;
			left /= 4;
			if (left >= max)
				break;

		}
		int ar1 = 0, ar2 = 0, ar3 = 0, ar4 = 0;
		for (int i = 0; i < k; i++) {
			for (int j = 0; j < k; j++) {
				if (j == i || j == k - i - 1)
					printf("    *");
				else {
					if (i < (k / 2)) {
						if (j < i) {
							if (ar2 < r2)
								printf("%5d", ans2[ar2++]);
							else
								printf("    0");
						} else if (j > k - i - 1) {
							if (ar3 < r3)
								printf("%5d", ans3[ar3++]);
							else
								printf("    0");
						} else if (ar1 < r1)
							printf("%5d", ans1[ar1++]);
						else
							printf("    0");
					} else {
						if (j < k - i - 1) {
							if (ar2 < r2)
								printf("%5d", ans2[ar2++]);
							else
								printf("    0");
						} else if (j > i) {
							if (ar3 < r3)
								printf("%5d", ans3[ar3++]);
							else
								printf("    0");
						} else if (ar4 < r4)
							printf("%5d", ans4[ar4++]);
						else
							printf("    0");
					}
				}

			}
			printf("\n");
		}
		printf("\n");
	}
	return 0;
}

总结

时钟加法一定要记得用while,否则是60%。

出现概率需要用到字符串输出大整数,单靠精度是没有办法AC的,只能达到80%。

  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Loop_kc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值