华科计算机历年考研复试上机题

先来一个题目传送门

写这篇博客为了提醒自己做题过程中所犯错误。

代码语言:Object C

1. 矩阵转置
题目描述:输入一个N*N的矩阵,将其转置后输出。要求:不得使用任何数组(就地逆置)。

分析:循环将上三角的元素和对应位置的元素交换即可,当然也可以在输入的时候就调换位置。

code:

#include
#include
int arr[110][110];
int main(){ 
	//freopen("aa.txt", "r", stdin);
	int n, i, j;
	while(scanf("%d", &n) == 1){
		memset(arr, 0, sizeof arr);
		for(i = 0; i

2. 统计单词
题目描述:编一个程序,读入用户输入的,以“.”结尾的一行文字,统计一共有多少个单词,并分别输出每个单词含有多少个字符。 (凡是以一个或多个空格隔开的部分就为一个单词)

分析:scanf读入能分离空格,因此只要不断输入,并且判断输入的字符串最后一个是不是 . 即可

code:

#include
#include

int main(){
	//freopen("aa.txt", "r", stdin);
	char ch[1010];
	while(~scanf("%s", ch)){
		int cnt = 0;
		int len = strlen(ch), i;
		for(i = 0; i
3. IP地址
题目描述:输入一个ip地址串,判断是否合法。

分析:sscanf能将输入的字符串格式化输出,再check每一位的合法性即可。

code:

#include
int check(int a){
	if(a>=0 && a<=255) return 1;
	return 0;
}
int main(){
	int a, b, c, d;
	char ip[10100];
	while(~scanf("%s", ip)){
		sscanf(ip, "%d.%d.%d.%d", &a, &b, &c, &d); 
		if(check(a) && check(b) && check(c) && check(d) && a != 0) printf("Yes!\n");
		else printf("No!\n");
	}
	
}
4. 二叉排序树
题目描述:二叉排序树,也称为二叉查找树。可以是一颗空树,也可以是一颗具有如下特性的非空二叉树: 
1. 若左子树非空,则左子树上所有节点关键字值均不大于根节点的关键字值;
2. 若右子树非空,则右子树上所有节点关键字值均不小于根节点的关键字值; 
3. 左、右子树本身也是一颗二叉排序树。
 现在给你N个关键字值各不相同的节点,要求你按顺序插入一个初始为空树的二叉排序树中,每次插入后成功后,求相应的父亲节点的关键字值,如果没有父亲节点,则输出-1。

分析:比较正常的二叉排序树

code:

#include
#include
int pp = -1;
struct Node{
        int data;
        struct Node* lchild, *rchild;
};
struct Node * insert(struct Node* root, int num, int p){
        if(root == NULL){
                root = (struct Node*)malloc(sizeof(struct Node));
                root->data = num;
                root->lchild = NULL;
                root->rchild = NULL;
                pp = p;
                return root;
        }
        if(root->data >= num) root->lchild = insert(root->lchild, num, root->data);
        else root->rchild = insert(root->rchild, num, root->data);
        return root;
}
int main(){
        int n, num, i;
        while(~scanf("%d", &n)){
                struct Node* root = NULL;
                for(i = 0; i

还有一种结构体定义的方法,

typedef struct Node{
     int data;
     struct Node *next;
}Node, *LinkNode;
5. 字符串连接
题目描述: 不借用任何字符串库函数实现无冗余地接受两个字符串,然后把它们无冗余的连接起来。

分析:直接输出

code:

#include

int main(){
    char str1[110], str2[110];
    while(~scanf("%s %s", str1, str2)){
        printf("%s%s\n", str1, str2);
    }
    return 0;
    
}

6. a+b
题目描述:实现一个加法器,使其能够输出a+b的值。

分析:模拟大数加法,最后输出的时候直接输出字符数组会报错,改用按位输出。

code:

#include
#include

void reverse(char a[], int len){
	int i;
	for(i = 0; i
7. 排序
题目描述:对输入的n个数进行排序并输出。

分析:手写快排, 当然也可以直接调用qsort

code:

#include
int partition(int arr[], int left, int right){
	int tem = arr[left], i = left, j = right;
	while(i < j){
		while(i < j && tem <= arr[j]) j--;
		while(i < j && tem >= arr[i]) i++;
		if(i < j){
			int ttem = arr[i];
			arr[i] = arr[j];
			arr[j] = ttem;
		}
	}
	arr[left] = arr[i];
	arr[i] = tem;
	return i;

}
void sort(int arr[], int left, int right){
	if(left < right){
		int pos = partition(arr, left, right);
		sort(arr, left, pos-1);
		sort(arr, pos+1, right);
	}
}
int main(){
	//freopen("aa", "r", stdin);
	int n, arr[110], i;
	while(~scanf("%d", &n)){
		for(i = 0; i
8. 特殊排序
题目描述:输入一系列整数,将其中最大的数挑出(如果有多个,则挑出一个即可),并将剩下的数进行排序,如果无剩余的数,则输出-1。

分析:手写快排, 不输出末尾元素

code:

#include
int partition(int arr[], int left, int right){
	int tem = arr[left], i = left, j = right;
	while(i < j){
		while(i < j && tem <= arr[j]) j--;
		while(i < j && tem >= arr[i]) i++;
		if(i < j){
			int ttem = arr[i];
			arr[i] = arr[j];
			arr[j] = ttem;
		}
	}
	arr[left] = arr[i];
	arr[i] = tem;
	return i;

}
void sort(int arr[], int left, int right){
	if(left < right){
		int pos = partition(arr, left, right);
		sort(arr, left, pos-1);
		sort(arr, pos+1, right);
	}
}
int main(){
	//freopen("aa", "r", stdin);
	int n, arr[1110], i;
	while(~scanf("%d", &n)){
		for(i = 0; i
9. 二叉树遍历
题目描述:二叉树的前序、中序、后序遍历的定义: 前序遍历:对任一子树,先访问跟,然后遍历其左子树,最后遍历其右子树; 中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树; 后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根。 给定一棵二叉树的前序遍历和中序遍历,求其后序遍历(提示:给定前序遍历与中序遍历能够唯一确定后序遍历)。

分析:前序的根节点能把中序分成左右子树,递归建树

code:

#include
#include
#include

char pre[50], in[50];
typedef struct Node{
	char data;
	struct Node *lchild, *rchild;
}Node, *LNode;
LNode create(int pl, int pr, int il, int ir){
	if(pl > pr) return NULL;
	LNode root = (LNode)malloc(sizeof(Node));
	root->data =  pre[pl];
	int k;
	for(k = il; k<=ir; k++)
		if(pre[pl] == in[k]) break;
	int numleft = k-il;
	root->lchild = create(pl+1, pl+numleft, il, k-1);
	root->rchild = create(pl+numleft+1, pr, k+1, ir);
	return root;

}
void postT(LNode root){
	if(root == NULL) return ;
	postT(root->lchild);
	postT(root->rchild);
	printf("%c", root->data);
}
int main(){
	//freopen("aa", "r", stdin);
	while(~scanf("%s%s", pre, in)){
		LNode root = NULL;
		int preL = strlen(pre), inL = strlen(in);	
		root = create(0, preL-1, 0, inL-1);
		postT(root);
		printf("\n");
	}


	return 0;
}
10. 奇偶校验
题目描述:输入一个字符串,然后对每个字符进行奇校验,最后输出校验后的二进制数(如'3’,输出:10110011)。

分析:先将输入转化为二进制数,再判断1的个数,为偶数则第7位为1(从0计数)。

code:

#include
#include

void odd(char ch){
	int num = (int)ch, len = 0, cnt = 0, i;
	char bnum[10];
	while(num){
		bnum[len++] = num%2 + '0';
		num /= 2;
	}
	for(i = 0; i-1; i--)
		printf("%c", bnum[i]);
	printf("\n");
}
void solve(char str[]){
	int len = strlen(str), i;
	for(i = 0; i
11. 最大的两个数
题目描述:输入一个四行五列的矩阵,找出每列最大的两个数。

分析:用了比较笨的方法。

code:

#include
 
int minn = 0x3fffffff;
int a[4][5], out[2][5];
int max1[5], max2[5];
int main(){
    //freopen("aa", "r", stdin);
    int i, j;
    while(~scanf("%d", &a[0][0])){
        for(i = 0; i<4; i++)
            for(j = 0; j<5; j++){
                if(i == 0 && j == 0) continue;
                scanf("%d", &a[i][j]);
                max1[j] = max2[j] = -minn;
            }
        for(j = 0; j<5; j++){
            for(i = 0; i<4; i++){
                if(a[i][j] >= max1[j]){
                    if(max1[j] > max2[j])
                        max2[j] = max1[j];
                    max1[j] = a[i][j];
                }
                else if(a[i][j] > max2[j])
                    max2[j] = a[i][j];
            }
        }
        for(j = 0; j<5; j++){
            int cnt = 0;
            for(i = 0; i<4; i++){
                if(cnt < 2 && (a[i][j] == max1[j] || a[i][j] == max2[j])){
                    out[cnt++][j] = a[i][j];
                    if(max1[j] == a[i][j]) max1[j] = -minn;
                    else max2[j] = -minn;
                }
                if(cnt >= 2) continue;
            }
        }
        for(i = 0; i<2; i++){
            for(j = 0; j<5; j++){
                printf("%d", out[i][j]);
                printf(j == 4?"\n":" ");
            }
        }
 
    }
    return 0;
 
 
}
11. 成绩排序
题目描述:有N个学生的数据,将学生数据按成绩高低排序,如果成绩相同则按姓名字符的字母序排序,如果姓名的字母序也相同则按照学生的年龄排序,并输出N个学生排序后的信息。

分析:qsort,重写cmp

code:

#include
#include

typedef struct Student{
	char name[110];
	int age, grade;
}Student;
Student stu[1010];
int cmp(const void *a, const void *b){
	struct Student *s1 = (Student *) a;
	struct Student *s2 = (Student *) b;
	if(s1->grade != s2->grade) return s1->grade-s2->grade;
	if(strcmp(s1->name, s2->name)) return strcmp(s1->name, s2->name);
	return s1->age-s2->age;
}
int main(){
	//freopen("aa", "r", stdin);
	int n, i;
	while(~scanf("%d", &n)){
		for(i = 0; i
12. 遍历链表
题目描述:建立一个升序链表并遍历输出。

分析:先排序,再尾插

code:

#include
#include

typedef struct Node{
	int data;
	struct Node *next;
}Node, * Linklist;

int arr[1007];
int cmp(const void *a, const void *b){
	return *(int *)a-*(int *)b;
}
Linklist insert(Linklist head, int num){
	Linklist p = head;
	while(p->next) p = p->next;
	Linklist tem = (Node *)malloc(sizeof(Node));
	tem->data = num;
	tem->next = NULL;
	p->next = tem;
	return head;
}
void show(Linklist head){
	Linklist p = head->next;
	while(p){
		printf("%d", p->data);
		printf(p->next != NULL?" ":"\n");
		p = p->next;
	}

}
int main(){
	//freopen("aa", "r", stdin);
	int n, num, i;
	while(~scanf("%d", &n)){
		Linklist head = (Linklist)malloc(sizeof(Node));
		head->next = NULL;
		for(i = 0; i
13. 守形数
题目描述:守形数是这样一种整数,它的平方的低位部分等于它本身。 比如25的平方是625,低位部分是25,因此25是一个守形数。 编一个程序,判断N是否为守形数。

分析:截断低位判等

code:

#include

int solve(int num){
	int tem = num*num, low = 0;
	if(tem > 1000){
		low = tem - (tem/1000)*1000;
	}
	else if(tem > 100){
		low = tem - (tem/100)*100;
	}
	else if(tem > 10)
		low = tem - (tem/10)*10;
	else low = 0;
	if(low == num) printf("Yes!\n");
	else printf("No!\n");
}

int main(){
	int n;
	//freopen("aa", "r", stdin);
	while(~scanf("%d", &n)){
		solve(n);
	}

	return 0;
}
14. 矩阵最大值
题目描述:编写一个程序输入一个mXn的矩阵存储并输出,并且求出每行的最大值和每行的总和。 要求把每行总和放入每行最大值的位置,如果有多个最大值,取下标值最小的那一个作为最大值。 最后将结果矩阵输出。

分析:设置sum,max,inf

code:

#include

int arr[110][110], sum[110], maxn[110];
int main(){
	//freopen("aa", "r", stdin);
	int m, n, i, j;
	int inf = -0x3fffffff;	
	while(~scanf("%d %d", &m, &n)){
		for(i = 0; iarr[i][j]?maxn[i]:arr[i][j];
			}
		}
		for(i = 0; i
15. 最小年龄的3个职工
题目描述:职工有职工号,姓名,年龄.输入n个职工的信息,找出3个年龄最小的职工打印出来。

分析:qsort,重写cmp

code:

#include

typedef struct Student{
	char name[11];
	int age, id;
}Student;
Student stu[33];
int cmp(const void *a, const void *b){
	Student *s1 = (Student *)a;
	Student *s2 = (Student *)b;
	if(s1->age != s2->age) return s1->age-s2->age;
	return s1->id-s2->id;
}
int main(){
	//freopen("aa", "r", stdin);
	int n, i;
	scanf("%d", &n);
	for(i = 0; i3?3:n;
	for(i = 0; i
16. 对称矩阵
题目描述:输入一个N维矩阵,判断是否对称。

分析:检查上三角即可

code:

#include

int arr[110][110];

int main(){
	//freopen("aa", "r", stdin);
	int n, i, j, flag;
	while(~scanf("%d", &n)){
		flag = 1;
		for(i = 0; i
17. A+B
题目描述:给定两个整数A和B,其表示形式是:从个位开始,每三位数用逗号","隔开。 现在请计算A+B的结果,并以正常形式输出。

分析:去逗号,判负

code:

#include
#include

int transfer(char a[]){
	int i = 0, neg = 0, sum = 0, len = strlen(a);
	if(a[i] == '-'){
		neg = 1;
		i++;
	}
	for(; i
18. 打印日期
题目描述:给出年分m和一年中的第n天,算出第n天是几月几号。

分析:判断闰年(能被4整除但不能被100整除,或者能被400整除),模拟

code:

#include
int isleapYear(int y){
	if(y%4==0 && y%100!=0) return 1;
	if(y%400 == 0) return 1;
	return 0;
}
void solve(int y, int d){
	int mon[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	if(isleapYear(y)) mon[1]++;
	int cnt = 0, m = 0, day = 0;
	while(cnt != d){
		cnt++;
		day++;
		if(day == mon[m]+1){
			m++;
			day = 1;
		}
	}
	printf("%d-%02d-%02d\n", y, m+1, day);
}
int main(){
	//freopen("aa", "r", stdin);
	int y, d, i;
	while(~scanf("%d %d", &y, &d)){
		solve(y, d);
	}
	return 0;

}
19. 二叉排序树
题目描述:输入一系列整数,建立二叉排序数,并进行前序,中序,后序遍历。

分析:坑点在于重复的元素不用输出,因此建树的时候不要插入即可

code:

#include
#include
typedef struct Node{
	int data;
	struct Node *lchild, *rchild;
}Node, *BiNode;
BiNode create(BiNode root, int num){
	if(root == NULL){
		root = (BiNode)malloc(sizeof(Node));
		root->data = num;
		root->lchild = NULL;
		root->rchild = NULL;
		return root;
	}
	if(num > root->data) root->rchild = create(root->rchild, num);
	else if(num < root->data) root->lchild = create(root->lchild, num);
	return root;
}
void preOrder(BiNode root){
	if(root == NULL) return;
	printf("%d ", root->data);
	preOrder(root->lchild);
	preOrder(root->rchild);
}
void inOrder(BiNode root){
	if(root == NULL) return ;
	inOrder(root->lchild);
	printf("%d ", root->data);
	inOrder(root->rchild);
}
void postOrder(BiNode root){
	if(root == NULL) return ;
	postOrder(root->lchild);
	postOrder(root->rchild);
	printf("%d ", root->data);
}
int main(){
	//freopen("aa", "r", stdin);
	int n, i, num;
	while(~scanf("%d", &n)){
		BiNode root = NULL;
		for(i = 0; i
20. 大整数排序
题目描述:对N个长度最长可达到1000的数进行排序。

分析:不要被吓到了,其实只是先比较长度再进行字符串比较

code:

#include
#include

typedef struct Big{
	char num[1010];
}Big;
Big arr[200];
int cmp(const void *a, const void *b){
	Big *b1 = (Big *)a;
	Big *b2 = (Big *)b;
	int len1 = strlen(b1->num), len2 = strlen(b2->num);
	if(len1 == len2)
		return strcmp(b1->num, b2->num);
	return len1-len2;
}
int main(){
	//freopen("aa", "r", stdin);
	int n, i;
	while(~scanf("%d", &n)){
		for(i = 0; i
21. N阶楼梯上楼问题
题目描述:一次可以走两阶或一阶,问有多少种上楼方式。(要求采用非递归)

分析:那就用递推喽,注意要用long long,虽然测试数据比较水。。

code:

//测试了输入89的时候达到long long 的最大值
#include
long long arr[91];
int main(){
    //freopen("aa", "r", stdin);
    int n, i;
    arr[1] = 1, arr[2] = 2;
    for(i = 3; i<90; i++)
        arr[i] = arr[i-1]+arr[i-2];
    while(~scanf("%d", &n))
        printf("%lld\n", arr[n]);
    return 0;
}
22. a+b
题目描述:计算a+b的和

分析:史上最水a+b

code:

#include

int main(){
    long long a, b;
    while(~scanf("%lld %lld", &a, &b))
        printf("%lld\n", a+b);
    
    return 0;
}
23. 回文字符串
题目描述:给出一个长度不超过1000的字符串,判断它是不是回文(顺读,逆读均相同)的。

分析:回文判断

code:

#include
#include

int isEcho(char str[]){
	int len = strlen(str);
	int i;
	for(i = 0; i
24. 找位置
题目描述:对给定的一个字符串,找出有重复的字符,并给出其位置,如:abcaaAB12ab12 输出:a,1;a,4;a,5;a,10,b,2;b,11,1,8;1,12, 2,9;2,13。

分析:WA了最多发的一题,bug在于我用的局部数组没有初始化,关键是本地还能对。。

code:

#include
#include
#include
 
void solve(char str[]){
    int i = 0, j = 0, len = strlen(str);
	int hash[300];
	memset(hash, 0, sizeof hash); //局部数组要初始化!!! 
    for(i = 0; i 1){
            int f = 1;
            for(j = i; j
25. 阶乘
题目描述:输入n, 求y1=1!+3!+...m!(m是小于等于n的最大奇数) y2=2!+4!+...p!(p是小于等于n的最大偶数)。

分析:模拟

code:

#include

typedef long long ll;
ll fac[100];
int main(){
	//freopen("aa", "r", stdin);
	int i, n;
	fac[1] = 1;
	for(i = 2; i<=100; i++)
		fac[i] = i*fac[i-1];
	while(~scanf("%d", &n)){
		ll sumOdd = 0, sumEven = 0;
		for(i = 1; i<=n; i++){
			if(i % 2 == 1) sumOdd += fac[i];
			else sumEven += fac[i];
		}
		printf("%lld %lld\n", sumOdd, sumEven);
	}

	return 0;
}
26. 八进制
题目描述:输入一个整数,将其转换成八进制数输出。

分析:除8取余

code:

#include
void solve(int x){
	char res[100];
	int len = 0, i;
	while(x != 0){
		res[len++] = x%8+'0';
		x /= 8;
	}
	for(i = 0; i

总结:
差不多历时3天才刷完,感觉是不是年代比较久远,这些机试题也都比较基础,虽然自己也有被一题WA哭的时候。。当然纯C编程能提高编程规范,总的来说还行。


























你可能感兴趣的:(机试)