西北农林科技大学2023级C语言期末考试题解

2024-02-05 22:20

本文主要是介绍西北农林科技大学2023级C语言期末考试题解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Readme

         本题解只提供了题目和题解代码,未提供讲解,后续会跟新B站视频详细讲解,大家可以关注等候。

        B站:沐晨汐er_

        链接:沐晨汐er_的个人空间-沐晨汐er_个人主页-哔哩哔哩视频 (bilibili.com)

        A题 WA了20多发哈哈哈哈

题目

E

题目描述

        现有n×n的棋盘,棋盘上每个格子只能放入黑白两种棋子中的一个,分别用字符'+'表示黑色棋子、'*'表示白色棋子、'0'表示未着子。
        编写Judge函数,Judge函数原型如下:
        int Judge(char **str, int n, char ch, struct solu *ps);
        其中,形参str是指向棋盘的指针,形参n表示棋盘大小(n×n),形参ch('+'、'*'分别表示黑白棋子)表示棋子颜色,形参ps是指向保存连珠方法的结构体变量。
        通过调用Judge函数,判断落子布局是否可以组成五子连珠,若可以则返回1,并将找到的第一个连珠方法保存在ps指向的结构体变量中;否则返回0。struct solu结构体的定义如下:

struct solu{int x;int y;char direction;
};

        其中,用x和y分别表示字符ch表示的棋子组成的第一个五子连珠的起始行号和起始列号(行号和列号均从0开始),用direction保存五子连珠的四种方向,可以在四种符号:'-','|','\','/'中取值,分别表示以x和y为起点,向右横向、向下竖向、向右下斜向、向左下斜向构成了五子连珠。
        五子连珠寻找的优先级规则为:行优先(即先判断第0行的所有位置,然后是第1行、第2行……依次类推),方向优先级判断顺序为:向右横向、向下竖向、向右下斜向、向左下斜向。

输入:

+ 20
0+0++*0+*+++000++0++
0+00+0+*0+*00*00***0
+0+0000+++*0+**+*0**
+**+0++*0*+0**0*0**0
*00*++0*0*++00*+00*0
*+*0*++*00*+0+0+**+0
+*+++0+0000+0***+**+
00*0+*0**+*0*000**++
*+**000+0+***++**+++
*00+*+*+00++0***0*0*
+*0**++0++*0+****00*
*+**+++0++++*0000+++
+*+000*0**++*+**+0**
+*0****+000*++++0*0*
+**0*+*00+000*0**+0+
0**+**+***0*+**00+*0
*+0++***0000+*+++0**
+0**+0+++*+0++**+000
**++++**00++00*++0*+
00*000+00++00+0+*+00
说明:分别用字符'+'、'*'、'0'代表黑子、白子、未着子,第一行输入"+ 20"表示在20×20的棋盘上对黑子是否能够组成五子连珠进行判断。

输出:

1 1 \
说明:该结果表明第1行,第1列,有一个由'+'组成的向右下斜向的五子连珠方案,是满足条件的第一个解

代码

// E.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>struct solu
{int x;int y;char direction;
};int Judge(char **str, int n, char ch, struct solu *ps){char t = '\0';for (int i = 0; i < n; i++){for (int j = 0; j < n; j++){if (str[i][j] == ch){if (j <= n-5 && str[i][j+1]==ch && str[i][j+2]==ch &&str[i][j+3]==ch && str[i][j+4]==ch){t = '-';	}else if (i <= n-5 && str[i+1][j]==ch && str[i+2][j]==ch &&str[i+3][j]==ch && str[i+4][j]==ch){t = '|';	}else if (i <= n-5 && j <= n-5 && str[i+1][j+1]==ch && str[i+2][j+2]==ch &&str[i+3][j+3]==ch && str[i+4][j+4]==ch){t = '\\';	}else if (i <= n-5 && j >= 4 && str[i+1][j-1]==ch && str[i+2][j-2]==ch &&str[i+3][j-3]==ch && str[i+4][j-4]==ch){t = '/';	}}if (t != '\0'){ps->x = i;ps->y = j;ps->direction = t;return 1;}}}return 0;
}int main()
{int n, i;char ch;struct solu s = {-1, -1, ' '};scanf("%c%d", &ch, &n);char *board[n];for(i = 0; i < n; i++){board[i] = (char *)malloc((n+1)*sizeof(char));memset(board[i], 0, (n+1)*sizeof(char));scanf("%s", board[i]);}if (Judge(board, n, ch, &s) == 1)printf("%d %d %c\n", s.x, s.y, s.direction);elseprintf("0\n");for(i = 0; i < n; i++){free(board[i]);}return 0;
}

D

题目描述

        给定一个有m个元素(m<50)的正整数整型数组nums和一个正整数k(0<k<20),现需要向nums数组中追加填充k个最小的未出现在数组nums中且互不相同的正整数,要求使填充后数组的各元素的累加和最小。请编写函数MinInsert()返回填充到nums中的k个整数之和。

        函数原型:int MinInsert(int *pnums, int m, int k);
        其中,形参pnums是指向nums整型数组的指针,形参m是数组元素的个数,形参k是要填充的正整数个数。
        函数算法请参考下面的流程图。

        注意:不能改变指定函数原型,仅需提交MinInsert()函数及其调用的自定义函数的实现代码。

        示例 1:
        输入:nums = {1,4,25,10,25}, k = 2
        输出:5
        解释:向数组中填充的两个互不相同且未出现的正整数是 2 和 3 。nums 最终元素和为 1 + 4 + 25 + 10 + 25 + 2 + 3 = 70 ,这是所有情况中的最小值。
        所以填充到数组中的两个整数之和是 2 + 3 = 5 ,所以返回 5 。

        示例 2:
        输入:nums = {5,6}, k = 6
        输出:25
        解释:向数组中填充的六个互不相同且未出现的正整数是 1 、2 、3 、4 、7 和 8 。nums 最终元素和为 5 + 6 + 1 + 2 + 3 + 4 + 7 + 8 = 36 ,这是所有情况中的最小值。
        所以填充到数组中的六个整数之和是 1 + 2 + 3 + 4 + 7 + 8 = 25 ,所以返回 25 。

        请参考下面的流程图编写代码。其中,gap是数组中的间隙。要循环判定数组的间隙大小,当间隙gap大于待填数量k时,依次填入整数;否则依次填满间隙,再调整待填数量k。最后如未达到要求的待填数量,则继续在尾部填充。

      

代码

// D.
#include <stdio.h>int MinInsert(int *pnums, int m, int k){int *t = pnums;for (int i = 0; i < m; i++){for (int j = 0; j < m; j++){if (t[j] > t[i]){int x = t[i];t[i] = t[j];t[j] = x;}}		}int sum = 0, cnt = 0;for (int i = 0; i < m; i++){if (i == 0){int cha = t[i] - 0;if (cha > 1){for (int j = 1; j < t[i]; j++){sum += j;cnt++;if (cnt == k) return sum; }}}else{int cha = t[i] - t[i-1];if (cha > 1){for (int j = t[i-1]+1; j < t[i]; j++){sum += j;cnt++;if (cnt == k) return sum; }}}}if (cnt < k){ int x = t[m-1]+1;while (cnt != k){sum += x;x++;cnt++;}}return sum;
}int a[N] = {5,8,13};
void solve() {cout << MinInsert(a,3,15) << endl;
}signed main() {int t = 1;while(t--) {solve();}return 0;
}

C

题目描述

        假定有下面的结构体:

typedef struct {unsigned int year;   /* 有效年份 1900~2050 年*/unsigned int month;unsigned int day;
} Date, *PDate;

        请实现下面的两个函数,其原型要求如下:
        int ToDate(char *str, PDate pd);
        int DaysCount(PDate sdate, PDate edate);
        ToDate()函数将字符串str中的合法日期存入指针变量pd指向的结构体成员中,其中字符串str的基本形式为“YYYY-MM-DD”,YYYY代表年,MM代表月,DD代表日,如str为“2023-12-30”,则ToDate()函数的功能是将2023、12、30分别存入pd->year、pd->month、pd->day中。如果str中的日期数值范围或数据格式非法,函数返回-1,正常返回0。
        DaysCount()函数计算两个日期sdate和edate之间差距是多少天,并返回计算结果。

输入:

2008-08-08
2023-12-30

输出:

5622

可以使用sscanf函数从字符串str中将年月日读取为整数,例如,sscanf(str, "%d-%d-%d", &year, &month, &day)。
另外,提供以下日期计算结果,供程序测试使用。

  • 1949年10月01日开国大典,至今(2023年12月30日)已过27118天。
  • 1950年10月25日抗美援朝,至今(2023年12月30日)已过26729天。
  • 今天是2023年12月30日,距离西北农林科技大学90周年校庆(2024年09月10日),还有255天。
  • 2023年09月11日开学,至今(2023年12月30日)已过110天。

代码

// C.
#include <stdio.h>
#include <stdlib.h>typedef struct {unsigned int year;unsigned int month;unsigned int day;
} Date, *PDate;int is_leap(int);
int month_days(int ,int);int ToDate(char *str, PDate pd){	int year,month,day;if ((sscanf(str, "%d-%d-%d", &year, &month, &day)) == 3){if (year >= 1900 && year <= 2050 && month >= 1 && month <= 12 && day >= 1 && day <= 31){pd->day = day;pd->month = month;pd->year = year;return 0;}return -1;}return -1;
}
int DaysCount(PDate sdate, PDate edate){int res = 0;// 开始那年 int flag = is_leap(sdate->year);res += month_days(sdate->month,flag) - sdate->day;for (int i = sdate->month+1; i <= 12; i++){res += month_days(i,flag);}// 后面的每一年 for (int i = sdate->year+1; i <= edate->year; i++){res += is_leap(i) ? 366 : 365;}// 减去多加的flag = is_leap(edate->year);res -= month_days(edate->month,flag) - edate->day;for (int i = edate->month+1; i<= 12; i++){res -= month_days(i,flag);} return res;
}int main()
{char str1[12], str2[12];Date sd, ed;fgets(str1, 12, stdin);fgets(str2, 12, stdin);if (ToDate(str1, &sd) == 0 && ToDate(str2, &ed) == 0)printf("%d\n", DaysCount(&sd, &ed));elseprintf("input data is invalid.\n");return 0;
}int is_leap(int year)
{return ((year%4==0&&year%100!=0)||year%400==0);
}int month_days(int month, int leap)
{int m_days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};if(month == 2)return (leap == 1) ? 29 : 28;elsereturn m_days[month];
}

B(?)

疑问

        不懂为什么排序的算法,冒泡排序(稳定性算法)过85%,选择排序1.0过92%最基础的选择排序2.0AC了有大佬可以解释一下吗??

题目描述   

        从二进制文件“stud.dic”中读取指定范围内的学生数据,并使用结构体、文件操作、函数指针等实现对各科成绩的升、降序通用化排序。程序主体框架已完成,请仔细阅读已有代码,并完成下面的两个函数:

1.通用排序
        函数原型为:void sort(stu *stud, int mode, int sub, int n);
        其中,形参sub用于指定需要排序的科目,取值为0、1或2代表的科目编号,形参mode用于指定排序模式,1表示升序,2表示降序,从而实现对形参n指定的n个学生成绩进行排序,形参stud是需要参与排序学生的数组首地址指针。

2.从二进制文件读入指定数据
        函数原型为:stu *read( FILE *fp, int m, int n);
        其中,形参fp传入的是已打开二进制文件的文件指针,形参m用于指定范围的起始位置(从0开始编号), 形参n用于指定需要读取的学生数据个数。在函数内部,用动态内存分配存储空间,读入指定的数据到分配的空间后,返回其首地址。

注意:

  1. 在程序主体框架中,已给出了结构体、主函数、辅助函数类型定义以及所需要完成的函数原型。
  2. 不能改变程序主体框架和指定函数原型,仅需提交sort()和read()函数及其调用的自定义函数的实现代码。
  3. 在二进制文件中,学生信息最多为30条,且姓名中可能会有空格,如:“白 莹”,成绩中可能含有小数。

输入:

起始学生序号m,学生数量n,排序方式mode,排序科目编号sub

0 3 1 0

输出:

从第m个开始的n个学生信息,并以mode方式对科目sub排序

0th: 2009011360 卢 莹 13.27 85.45 26.72
1th: 2010036201 张 阳 87.10 54.00 63.90
2th: 2010036209 赵扶强 90.50 54.00 65.00

代码

// B.
#include <stdio.h>
#include <stdlib.h>#define M 30typedef struct STUDENT
{int studentID;char studentName[10];float score[3];
} stu, *pstu;
typedef int (*CmpFunPtr)(float, float);  /* 定义函数指针类型CmpFunPtr,该类型的指针指向的函数应该返回一个整型数据,且含有两个float型形参。 */int compareA(float, float);    /* 降序排序比较函数 */
int compareD(float, float);    /* 升序排序比较函数 */
stu *read(FILE *fp, int m, int n);
void sort(stu *stud, int mode, int sub, int n);
void print(pstu stud, int n);
CmpFunPtr setmode(int mode);        /* 返回一个CmpFunPtr类型的函数指针 */int main()
{struct STUDENT *stud;FILE *fp;int m, n, mode, sub;scanf("%d%d%d%d",&m, &n, &mode, &sub);if(m < 0 || m > M || n < 0 || n+m > M || (mode != 1 && mode != 2) || (sub != 0 && sub !=1 && sub != 2)){printf("error!\n");exit(0);}fp = fopen("stud.dic", "rb");if(fp == NULL )exit(0);stud=read(fp, m, n);sort(stud, mode, sub, n);print(stud, n);free(stud);fclose(fp);return 0;
}CmpFunPtr setmode(int mode)
{if (mode == 1)return compareD;elsereturn compareA;
}
void print(pstu stud, int n)
{int i;for(i = 0; i < n; i++){printf("%dth: %d %s %.2f %.2f %.2f\n", i, stud[i].studentID,stud[i].studentName, stud[i].score[0], stud[i].score[1], stud[i].score[2]);}
}int compareA(float x, float y)
{return x > y;
}
int compareD(float x, float y)
{return x < y;
}
stu *read(FILE *fp, int m, int n)
{stu *stud = (stu *)malloc(n * sizeof(stu));if (stud == NULL){exit(1);}fseek(fp, m * sizeof(stu), SEEK_SET);fread(stud, sizeof(stu), n, fp);return stud;
}void sort(stu *stud, int mode, int sub, int n){// 选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法。// 冒泡排序、插入排序、归并排序、基数排序是稳定的排序算法。//	  //冒泡 
//    for (int i = 0; i < n; i++){
//        for (int j = 0; j < n-1; j++){
//        	if (mode == 1){  // 升序 
//	            if (stud[j].score[sub] > stud[j+1].score[sub]){
//	                stu temp = stud[j];
//	                stud[j] = stud[j+1];
//	                stud[j+1] = temp;
//	            }	        		
//			}else{ // 降序 
//	            if (stud[j].score[sub] < stud[j+1].score[sub]){
//	                stu temp = stud[j];
//	                stud[j] = stud[j+1];
//	                stud[j+1] = temp;
//	            }				
//			}
//        }
//    }// 选择 1.0for (int i = 0; i < n - 1; i++){for (int j = i+1; j < n; j++){if (mode == 1){  // 升序 if (stud[j].score[sub] < stud[i].score[sub]){ // 比该位置小就换 stu temp = stud[i];stud[i] = stud[j];stud[j] = temp;}	        		}else{ // 降序 if (stud[j].score[sub] > stud[i].score[sub]){stu temp = stud[i];stud[i] = stud[j];stud[j] = temp;}				}}}
//	// 选择 2.0
//    for (int i = 0; i < n - 1; i++){
//    	int idx = i;
//        for (int j = i+1; j < n; j++){
//        	if (mode == 1){  // 升序 
//	            if (stud[j].score[sub] < stud[idx].score[sub]){
//					idx = j;
//	            }	        		
//			}else{ // 降序 
//	            if (stud[j].score[sub] > stud[idx].score[sub]){
//					idx = j;
//	            }				
//			}
//    	}
//    	stu temp = stud[i];
//        stud[i] = stud[idx];
//        stud[idx] = temp;
//	}
}

A(过 90%)

疑问

        不懂,说我越界了,求大佬指点,wa了20多发。。。。。。。。

题目描述   

        “行程长度编码(Run-Length Encoding,RLE)”是一种无损压缩编码方法,其核心思想是依次记录符号序列中的每个字符(忽略大小写)及其重复出现的次数。例如用户输入字符序列(字符串)AaABBBbCBB,则其RLE编码的结果为3A4B1C2B。
        下面的代码实现对输入字符串的RLE编码,现要求在函数int rle(char *code, const char *seq);及 函数readSeq(char *seq, int n);定义中的五个空白处填充适当的表达式,完成程序功能。
        其中:rle()函数形参seq为长度在(0, 80]间(strlen(seq)>0&&strlen(seq)≤80)的全部由大小写英文字母组成的字符串指针,形参code为RLE编码后的结果字符串指针。编码正常结束函数返回0;如字符串指针seq为空或字符串长度不合法时,不进行编码函数直接返回-1;当字符串seq中出现非英文字母的其他字符时,也不进行编码函数直接返回-2。
        readSeq()从键盘读取最多n个字符到seq字符串中,以回车符或EOF字符为结束标志。

输入1:

KAAAEE

输出1:

1K3A2E

输入2:

aaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbb

输出2:

10A10B10A10B10A10B10A10B

输入3:

abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefab

输出3:

1A1B1C1D1E1F1A1B1C1D1E1F1A1B1C1D1E1F1A1B1C1D1E1F1A1B1C1D1E1F1A1B1C1D1E1F1A1B1C1D1E1F1A1B1C1D1E1F1A1B1C1D1E1F1A1B1C1D1E1F1A1B1C1D1E1F1A1B1C1D1E1F1A1B1C1D1E1F1A1B

代码

// A. 
#include <stdio.h>
#include <string.h>#define MAX_SEQ_LEN 80int rle(char *code, const char *seq);
int readSeq(char *seq, int n);int main()
{char seq[MAX_SEQ_LEN + 1] = { 0 };char code[2 * MAX_SEQ_LEN + 1];int r;readSeq(seq, MAX_SEQ_LEN);r = rle(code, seq);switch (r) {case 0:printf("%s\n", code);break;case -1:printf("Length is inValid.\n");break;case -2:printf("Has inValid character.\n");break;}return 0;
}/* 以上代码禁止提交 */
int readSeq(char *seq, int n)
{int ch, k;k = 0;while ((ch = getchar())) {if (ch == '\n' || ch == EOF || k == n) break;  // if (__________(1)_________)seq[k++] = ch;}seq[k] = '\0';   // _____(2)______;return k;
}int rle(char *code, const char *seq)
{int i, len = 0;if (strlen(seq) <= 0 || strlen(seq) > 80) return -1;  // if (________(3)_______)const char *p = seq; // p = seq; 
//    char *ptr = code;// while (*p != '\0' && strlen(code) < strlen(seq)*2-1)   while (*p) {   // while (____(4)____)char token = *p;i = 1;token &= 0xDF;if (token > 'Z' || token < 'A')return -2;while ((*(++p) == token || *(p) == token+32) && *p != '\0'){ // while (___(5)___)i++;}
//		while (1){
//			p++;
//			if (*p == '\0') break;
//        	if (*p != token && *p != token+32) break;
//			i++; 
//		}len = sprintf(code, "%d%c", i, token);code += len;}*code = '\0';
//    code = ptr;return 0;
}// aaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbb
// abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefab

这篇关于西北农林科技大学2023级C语言期末考试题解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/682332

相关文章

C语言中的数据类型强制转换

《C语言中的数据类型强制转换》:本文主要介绍C语言中的数据类型强制转换方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C语言数据类型强制转换自动转换强制转换类型总结C语言数据类型强制转换强制类型转换:是通过类型转换运算来实现的,主要的数据类型转换分为自动转换

利用Go语言开发文件操作工具轻松处理所有文件

《利用Go语言开发文件操作工具轻松处理所有文件》在后端开发中,文件操作是一个非常常见但又容易出错的场景,本文小编要向大家介绍一个强大的Go语言文件操作工具库,它能帮你轻松处理各种文件操作场景... 目录为什么需要这个工具?核心功能详解1. 文件/目录存javascript在性检查2. 批量创建目录3. 文件

C语言实现两个变量值交换的三种方式

《C语言实现两个变量值交换的三种方式》两个变量值的交换是编程中最常见的问题之一,以下将介绍三种变量的交换方式,其中第一种方式是最常用也是最实用的,后两种方式一般只在特殊限制下使用,需要的朋友可以参考下... 目录1.使用临时变量(推荐)2.相加和相减的方式(值较大时可能丢失数据)3.按位异或运算1.使用临时

使用C语言实现交换整数的奇数位和偶数位

《使用C语言实现交换整数的奇数位和偶数位》在C语言中,要交换一个整数的二进制位中的奇数位和偶数位,重点需要理解位操作,当我们谈论二进制位的奇数位和偶数位时,我们是指从右到左数的位置,本文给大家介绍了使... 目录一、问题描述二、解决思路三、函数实现四、宏实现五、总结一、问题描述使用C语言代码实现:将一个整

C语言字符函数和字符串函数示例详解

《C语言字符函数和字符串函数示例详解》本文详细介绍了C语言中字符分类函数、字符转换函数及字符串操作函数的使用方法,并通过示例代码展示了如何实现这些功能,通过这些内容,读者可以深入理解并掌握C语言中的字... 目录一、字符分类函数二、字符转换函数三、strlen的使用和模拟实现3.1strlen函数3.2st

Go语言中最便捷的http请求包resty的使用详解

《Go语言中最便捷的http请求包resty的使用详解》go语言虽然自身就有net/http包,但是说实话用起来没那么好用,resty包是go语言中一个非常受欢迎的http请求处理包,下面我们一起来学... 目录安装一、一个简单的get二、带查询参数三、设置请求头、body四、设置表单数据五、处理响应六、超

C语言中的浮点数存储详解

《C语言中的浮点数存储详解》:本文主要介绍C语言中的浮点数存储详解,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、首先明确一个概念2、接下来,讲解C语言中浮点型数存储的规则2.1、可以将上述公式分为两部分来看2.2、问:十进制小数0.5该如何存储?2.3 浮点

基于Python实现多语言朗读与单词选择测验

《基于Python实现多语言朗读与单词选择测验》在数字化教育日益普及的今天,开发一款能够支持多语言朗读和单词选择测验的程序,对于语言学习者来说无疑是一个巨大的福音,下面我们就来用Python实现一个这... 目录一、项目概述二、环境准备三、实现朗读功能四、实现单词选择测验五、创建图形用户界面六、运行程序七、

使用Go语言开发一个命令行文件管理工具

《使用Go语言开发一个命令行文件管理工具》这篇文章主要为大家详细介绍了如何使用Go语言开发一款命令行文件管理工具,支持批量重命名,删除,创建,移动文件,需要的小伙伴可以了解下... 目录一、工具功能一览二、核心代码解析1. 主程序结构2. 批量重命名3. 批量删除4. 创建文件/目录5. 批量移动三、如何安

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本