中南大学(CSU)2022级期末考试

打印幸运树(20分)

[命题人 : 外部导入]
时间限制 : 1.000 sec 内存限制 : 128 MB

题目描述
新年快到了,小南想打印一些高度为2n+1的幸运树。幸运树的树冠高度为n+1,树干的高度为n,由“*”组成,你能帮帮他吗?
输入
多个样例。每个样例包含一个正整数n(1≤n≤50)。
输出
每个样例输出一个满足条件的幸运树,不同样例输出结果之间没有空行。
样例输入 Copy
1
3
样例输出 Copy

 *
***
 *
   *
  ***
 *****
*******
   *
   *
   *

循环输出空格和星星。找规律

判断IP地址(20分)

[命题人 : 外部导入]
时间限制 : 1.000 sec 内存限制 : 128 MB

题目描述

小南最近在信息楼管理网络IP地址,IP地址的合法表示形式为a.b.c.d(0≤a,b,c,d≤255)。现在给你一个IP地址,请你判断是不是合法的IP地址。

输入
多个样例。每个样例输入一行形式为a.b.c.d的用点“.”分隔的四个整数,这些整数满足int类型范围。

输出
如果IP地址合法则输出Yes,不合法则输出No。每个样例输出结果占一行。

样例输入 Copy
0.0.0.0
3.9.12.26
277.1.1.6
样例输出 Copy
Yes
Yes
No

#include<stdio.h>
#define judge(m)\
if(!(m>=0&&m<=255))\
flag=0;
int main(void)
{
	int a, b, c, d;
	while (~scanf("%d.%d.%d.%d", &a, &b, &c, &d))
	{
		int flag = 1;
		judge(a);
		judge(b);
		judge(c);
		judge(d);
		if (flag)
			printf("Yes\n");
		else
			printf("No\n");
	}
}

填充立方体(10分)

[命题人 : 外部导入]
时间限制 : 1.000 sec 内存限制 : 128 MB

题目描述

期中考试小南设计的填数游戏非常有意思,于是老师要小南再设计一个新的填数游戏用于期末考试。就是用“*”画出一个立方体,并将立方体图形的三面分别按照规律填上大写字母“A”“Z”字母、小写字母“a”“z”和数字“1”~“9”。填充的过程按照字母和数字的顺序从上到下从左至右进行。
立方体的边长n定为多少好呢?小南让老师给出一个句子,将句子的长度len和句子中单词的个数m的最大公约数设定为立方体的边长n。例如:当老师给出的句子为“you like these things sun stars and moon”时,句子长度len为40,单词个数m为8,最大公约数为8。因此立方体的边长n为8,对应的图形为:

注意,当n为1时,对应的立方体图形为一个星号*。同时,老师要求小南将句子中的单词颠倒顺序输出,即输出“moon and stars sun things these like you”,你能帮小南编程实现吗?
输入
多个样例。 每个样例包含一个由字母组成的句子,句子的首尾没有多余的空格,长度不超过200,句子中的单词之间用一个空格分开。
输出
每个样例首先输出一个颠倒单词顺序的句子,然后按照填充要求输出一个正确的立方体图形。样例输出结果之间用一个空行分开。
样例输入 Copy
I do
you like these things sun stars and moon
you love csu
样例输出 Copy
do I
**


**

moon and stars sun things these like you
********
ABCDEF*
GHIJKL1*
MNOPQR23*
STUVWX456*
YZABCD7891*
EFGHIJ23456*
*789123
abcdef45678

ghijkl9123

mnopqr456

stuvwx78

yzabcd9

efghij


csu love you


A*
*1
a


int findGCD(int a, int b)
{
	int ans = 0;
	while (ans = a % b)
	{
		a = b;
		b = ans;
	}
	return b;
}
#include<stdio.h>
#include<string.h>
int main(void)
{
	
	while (1)
	{   char arr[1000][1000] = { 0 };
	    int i, len = 0;
		for (i = 0; i < 100; i++)
		{
			if (scanf("%s", arr[i]) == EOF)
			{
				return 0;
			};
			len += strlen(arr[i]);
			char ch = getchar();
			if (ch == '\n')
			{
				break;
			}
			len++;
		}
		for (int m = i; m> 0; m--)
		{
			printf("%s ", arr[m]);
		}
		printf("%s\n", arr[0]);
		int n = findGCD(len, i + 1);
		if (n == 1)
		{
			printf("*\n\n");
			continue;
		}
		//rhe first row
		for (int i = 1; i <= n - 1; i++)
		{
			printf(" ");
		}
		for (int i = 1; i <= n; i++)
		{
			printf("*");
		}
		printf("\n");

		char daxie = 'A';
		int integer = 1;
		for (int i = n - 2; i >= 1; i--)
		{
			for (int m = 1; m <= i; m++)
			{
				printf(" ");
			}
			printf("*");
			for (int m = 1; m <= n - 2; m++)
			{
				if (daxie == 'Z'+1)
					daxie = 'A';
				printf("%c", daxie++);
			}
			printf("*");
			for (int m = 1; m <= n - 2 - i; m++)
			{
				if (integer == 10)
					integer = 1;
				printf("%d", integer);
				integer++;
			}
			printf("*\n");
		}

		for (int i = 1; i <= n; i++)
		{
			printf("*");
		}
		for (int i = 1; i <= n - 2; i++)
		{
			if (integer == 10)
				integer = 1;
			printf("%d", integer);
			integer++;
		}
		printf("*\n");
		
		char xiaoxie = 'a';
		for (int i = n - 3; i >= 0; i--)
		{
			printf("*");
			for (int m = 1; m <= n - 2; m++)
			{
				if (xiaoxie == 'z' + 1)
					xiaoxie = 'a';
				printf("%c", xiaoxie++);
			}
			printf("*");
			for (int m = 1; m <= i; m++)
			{
				if (integer == 10)
					integer = 1;
				printf("%d", integer);
				integer++;
			}
			printf("*\n");
		}

		for (int i = 1; i <= n; i++)
		{
			printf("*");
		}
		printf("\n\n");
	}

	return 0;
}

世界杯球赛(10分)

[命题人 : 外部导入]
时间限制 : 1.000 sec 内存限制 : 128 MB

题目描述
小南是足球球迷,每届的世界杯球赛必看。本次世界杯小组赛每个小组n只球队,每个小组n(n-1)/2场比赛。记分形式为“球队名1:球队名2 进球数1:进球数2”。世界杯小组赛结束后,老师给了小南一个任务,要他根据比赛结果对小组中的n支球队进行排名。排名规则为:
(1)首先按照累积得分排序,胜一场得3分,平一场得1分,负一场得0分。累积分数高的球队排名在前。
(2)如果累积分数相同者,按照净胜球数排序,净胜球多的球队排名在前。
(3)如果累积分数相同,净胜球数也相同,则按照两只球队名字的字母顺序排序,从第一个字母依次比较直到决出排名为止,如Brazil排名在Japan之前。
输入
多个样例。 每个样例的第一行为正整数n (2≤n≤ 10),表示小组球队数。
接下来的n(n-1)/2行表示小组每一场比赛的成绩,形式为si:sj x:y。s1, s2, …,sn表示球队名,长度不超过20;x和y表示进球数,满足0≤x,y≤ 20,|x-y|表示胜方的净胜球数。
输出
每个样例按照排名顺序输出小组各球队的名称,球队名称之间用一个空格隔开。每个样例输出一行。
样例输入 Copy
4
AAA:BBB 3:1
AAA:CCC 2:1
BBB:CCC 5:0
AAA:DDD 2:0
DDD:BBB 1:1
DDD:CCC 1:3
3
Aa:Bbb 2:1
Bbb:Ee 3:1
Ee:Aa 1:1
样例输出 Copy
AAA BBB CCC DDD
Aa Bbb Ee

	#include<stdio.h>
	#include<string.h>
	#include<stdlib.h>
	struct namejiegou {
		char name[210];
	};
	struct team {
		struct namejiegou namejiegouti;
		int score, jingshengqiushu;
	};
	int compare(const void* p, const void* q)
	{
		struct team* p1 = p;
		struct team* q1 = q;
		if (p1->score > q1->score)
			return -1;
		else if (p1->score < q1->score)
			return 1;
		else if (p1->jingshengqiushu > q1->jingshengqiushu)
			return -1;
		else if (p1->jingshengqiushu < q1->jingshengqiushu)
			return 1;
		else
		{
			return strcmp(p1->namejiegouti.name, q1->namejiegouti.name);
			int i = 0;
			int a, b;
			for (;;)
			{
				if (p1->namejiegouti.name[i] >= 'a')
					a = p1->namejiegouti.name[i] - 'a';
				else
					a = p1->namejiegouti.name[i] - 'A';
				if (q1->namejiegouti.name[i] >= 'a')
					b = q1->namejiegouti.name[i] - 'a';
				else
					b = q1->namejiegouti.name[i] - 'A';
				if (a > b)
					return 1;
				else if (a < b)
					return -1;
				else
					;
			}
		}
	}
	int findqiudui(char* name, struct team p[10],int *top, struct team*qiudui)
	{
		int i = 0;
		for (;  i < *top&&strcmp(name, p[i].namejiegouti.name) ; i++)
			;
		if (i == *top) {
			(*top)++;
			qiudui[i].jingshengqiushu = 0;
			qiudui[i].score = 0;
		}//biaoshi xinqiudui
	    return i;
	}
	//另一种获取名字的办法
	void getname(char* n)
	{
		char ch; int m = 0;
		scanf(" %c", &ch);
		if (ch == ':') scanf("%c", &ch);
		while (ch != ':'&&ch!=' ')
		{
			n[m++] = ch;
			scanf("%c", &ch);
		}
		n[m++] = '\0';
	}
	int main(void)
	{
		int n;
		while (~scanf(" %d ", &n))
		{
			struct team qiudui[20];
	
			memset(qiudui, 0, sizeof(qiudui));
			int top=0;//top指向最高一个的下一个
			for (int i = 1; i <= (n - 1) * n / 2; i++)
			{
				struct namejiegou name1, name2;
				char temp;
				char tempname0[100] = { 0 };
				char* p = NULL;
				scanf("%s ", tempname0);
				//通过字符串方法将两个名称在‘:’处分离
				p = strchr(tempname0, ':');
				*p = '\0';
				strcpy(name1.name, tempname0);
				strcpy(name2.name, p + 1);
				int x = 0, y = 0;
				scanf("%d:%d", &x,  &y);
				int qiudui1xuhao, qiudui2xuhao;
				qiudui1xuhao = findqiudui(name1.name, qiudui, &top,qiudui);
				qiudui2xuhao = findqiudui(name2.name, qiudui, &top,qiudui);
				qiudui[qiudui1xuhao].namejiegouti = name1;
				qiudui[qiudui2xuhao].namejiegouti = name2;
				if (x > y)
				{
					qiudui[qiudui1xuhao].score += 3;
					qiudui[qiudui1xuhao].jingshengqiushu += x-y;
				}
				else if (x < y)
				{
					qiudui[qiudui2xuhao].score += 3;
					qiudui[qiudui2xuhao].jingshengqiushu += y-x;
	
				}
				else
				{
					qiudui[qiudui2xuhao].score += 1;
					qiudui[qiudui1xuhao].score += 1;
				}
			}
			qsort(qiudui, n, sizeof(struct team), compare);
			for (int i = 0; i < n-1; i++)
			{
				printf("%s ", qiudui[i].namejiegouti.name);
			}
			printf("%s\n", qiudui[n - 1].namejiegouti.name);
		}
		return 0;
	}

超递增序列(20分)

[命题人 : 外部导入]
时间限制 : 1.000 sec 内存限制 : 128 MB

题目描述
小南有很多长度不同的正整数序列,他发现其中有些序列有一个共同的特点,就是序列中元素排序后,可形成超递增序列。超递增序列是指后面的数大于前面所有数的和,例如序列{1,3,8,14,29}就是超递增的,因为1<3、1+3<8、1+3+8<14、 1+3+8+14<29。现在有若干个长度为n(1≤n≤100)的序列,请你帮他判断是否可以排序后形成超递增序列。
输入
多个样例。每个样例包含2行输入:第1行包含一个正整数n(1≤n≤100),第2行包含n个正整数ai (1 ≤ ai ≤ 106)。
输出
对于每个样例,如果排序后能形成超递增序列则输出Yes,否则输出No。每个样例结果输出占一行。
样例输入 Copy
1
2
5
14 8 1 3 29
3
1 2 3
样例输出 Copy
Yes
Yes
No

#include<stdio.h>
#include<stdlib.h>
int compare(const void* p, const void* q)
{
	int* p1 = p;
	int* q1 = q;
	if (*p1 > *q1)
		return 1;
	if (*p1 == *q1)
		return -1;
	return 0;
}
int arr[1000000] = { 0 };
int main(void)
{
	int n;
	while (~scanf("%d", &n))
	{
	
		for (int i = 0; i < n; i++)
		{
			scanf("%d", &arr[i]);
		}
		qsort(arr, n, sizeof(int), compare);
		int sum = 0; int i;
		for (i = 0; i <=n-1 ; i++)
		{
			if (sum < arr[i])
				sum+=arr[i];
			else
				break;
		}
		if (i == n )
			printf("Yes\n");
		else
			printf("No\n");
	}
	return 0;
}

字符串相加(20分)

[命题人 : 外部导入]
时间限制 : 1.000 sec 内存限制 : 128 MB

题目描述
小南自学习C语言以来,做过很多关于加法的题目,整数相加、实数相加、分数相加、时钟相加等等。这一次,小南想试试字符串相加,字符串由小写字母“a”“z”组成,为了便于计算,将其编号为025。加法规则为:两个字符串中的字符从左至右按照对应位置相加变成一个新字符,不进位,如"abc"+“zbz”,有’a’+‘z’=‘z’,‘b’+‘b’=‘c’,‘c’+‘z’=‘b’,因此有"abc"+“zbz”=“zcb”。你能帮他编程实现吗?
输入
多个样例。每个样例包含两个字符串,字符串的长度len满足1≤n≤1000。
输出
对于每个样例,输出一个新的字符串。每个样例结果输出占一行。
样例输入 Copy
aa ccc
abcde bbb
abc zbz
样例输出 Copy
ccc
bcdde
zcb

#include<stdio.h>
#include<stdio.h>
void ans(char* longs, char* shorts )
{
	int s1 = strlen(longs), s2 = strlen(shorts);
	for (int index1 =0, index2 = 0;index2 < s2; index1++, index2++)
	{
		int num = (longs[index1] - 'a' + shorts[index2] - 'a')%26;
		printf("%c", num + 'a');
	}
	for (int i = s2; i < s1 ; i++)
	{
		printf("%c", longs[i]);
	}
	printf("\n");
}

int main(void)
{
	char s1[1000], s2[1000];
	while (~scanf("%s %s", s1, s2))
	{
		if (strlen(s1) > strlen(s2))
		{
			ans(s1, s2);
		}
		else
		{
			ans(s2, s1);
		}
	}
}

忌惯性思维
一开始把这道题看成右对齐相加了。当然不对。。。

总结

考点

每年基本上都有一道题是打印,像22年打印幸运数这种题要找规律。常见思路利用for循环,i可以初始等于某一个特征值,如空格数目,然后循环加减。

链表和结构体。

数组想要开大设置为全局变量。

数据大小的选取:题目中所给的数据不一定是int型。数组注意大小

可能的错误:

初始化,可利用memset(首地址,数字,字节数)。从首地址开始的字节初始化为那个数字;

题意理解错误。可能漏看,错看。解决方法逐句读。

大脑清晰很重要。在脑中先预演一遍程序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值