【C语言】学习记录——复习题

(一)到底是不是太胖了

据说一个人的标准体重应该是其身高(单位:厘米)减去100、再乘以0.9所得到的公斤数。真实体重与标准体重误差在10%以内都是完美身材(即 | 真实体重 − 标准体重 | < 标准体重×10%)。已知市斤是公斤的两倍。现给定一群人的身高和实际体重,请你告诉他们是否太胖或太瘦了。

输入格式:

输入第一行给出一个正整数N(≤ 20)。随后N行,每行给出两个整数,分别是一个人的身高H(120 < H < 200;单位:厘米)和真实体重W(50 < W ≤ 300;单位:市斤),其间以空格分隔。

输出格式:

为每个人输出一行结论:如果是完美身材,输出You are wan mei!;如果太胖了,输出You are tai pang le!;否则输出You are tai shou le!。

输入样例:

3
169 136
150 81
178 155

输出样例:

You are wan mei!
You are tai shou le!
You are tai pang le!

(1)实验代码

#include<stdio.h>
#include<math.h>
int main(void)
{
    int n;
    float h,w;
    float bw;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        scanf("%f %f",&h,&w);
        bw=(h-100.0)*1.8;
        if(fabs(w-bw)<bw*0.1)
        {
            printf("You are wan mei!\n");
        }
        else
        {
            if(w-bw>0)
            {
                printf("You are tai pang le!\n");
            }
            else
            {
                printf("You are tai shou le!\n");
            }
        }
    }
    return 0;
}

(2)设计思路

判断语句,先判断fabs(标准体重-体重)。如果是标准体重,直接输出;如果不是,则判断标准体重和体重之间的关系,输出是太瘦了还是太胖了。
要用到math库中的fabs()函数(如果是整型就用abs(),浮点类型用fabs())

(二)方阵循环右移

本题要求编写程序,将给定n×n方阵中的每个元素循环向右移m个位置,即将第0、1、⋯、n−1列变换为第n−m、n−m+1、⋯、n−1、0、1、⋯、n−m−1列。

输入格式:

输入第一行给出两个正整数m和n(1≤n≤6)。接下来一共n行,每行n个整数,表示一个n阶的方阵。

输出格式:

按照输入格式输出移动后的方阵:即输出n行,每行n个整数,每个整数后输出一个空格。

输入样例:

2 3
1 2 3
4 5 6
7 8 9
输出样例:

2 3 1
5 6 4
8 9 7
(1)实验代码

#include<stdio.h>
int main(void)
{
    int m, n; int a[6][6];
    scanf("%d %d", &m, &n);
    //m的值需要保证在n范围内
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            scanf("%d", &a[i][j]);
        }
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            printf("%d ",a[i][n-m+j]);//问题
        }
        printf("\n");
    }
    return 0;
}

(2)设计思路

二维数组的数据输入和输出

(3)所遇问题

用题目所给用例测试,出来的结果如下。
在这里插入图片描述
(4)改进方法

经过测试输入时没有问题,很明显第一列的输出有问题。
输出n-m+j每次的计算结果,发现有越界的情况。
为防止越界的情况,将(n-m+j)改为(n-m+j)%n,此外因为题目中没有限定m<n,所以将m的值改为m%n。

(5)终极代码

#include<stdio.h>
int main(void)
{
    int m, n; int a[6][6];
    scanf("%d %d", &m, &n);
    m=m%n;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            scanf("%d", &a[i][j]);
        }
    }
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            printf("%d ",a[i][(n-m+j)%n]);
        }
        printf("\n");
    }
    return 0;
}

(三)共用体类型

学校全体员工分为教师和行政人员两类。教师的数据包括:编号,姓名,职业(t),职称(教授professor,副教授associate professor,讲师lecturer等);行政人员的数据包括:编号,姓名,职业(w),部门号(100,200,300等)。要求输入若干人员的数据并能输出他们的资料,同时统计教师(tcount)和行政人员(wcount)的数量。使用动态内存分配函数实现。

输入格式:

输入第一行给出正整数n,随后给出n个员工的信息。

输出格式:

输出指定数量的员工信息,并在最后一行输出教师和行政人员的数量。

输入样例:

5
10000 jack t professor
20000 rose t associate professor
30000 mike w 100
40000 robin w 200
50000 lina t lecturer

输出样例:

10000 jack t professor
20000 rose t associate professor
30000 mike w 100
40000 robin w 200
50000 lina t lecturer
tcount = 3, wcount = 2

(1)实验代码

#include <stdio.h>
union Class
{
	int classes;
	char position[30];
};
struct Inf
{
	int number;
	char name[30];
	char job;
	union Class c;
}a[100];
int main(void)
{
	int n;
	int ct = 0, cw = 0;
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		scanf("%d %s %c",&a[i].number,a[i].name,&a[i].job);//问题b
		if (a[i].job == 't')
		{
			scanf("%s",a[i].c.position);//问题a
			ct++;
		}
		else
		{
			scanf("%d", &a[i].c.classes);
			cw++;
		}
	}
	for (int i = 0; i < n; i++)
	{
		if (a[i].job == 't')
		{
			printf("%d %s %c %s\n",a[i].number,a[i].name,a[i].job,a[i].c.position);
		}
		else
		{
			printf("%d %s %c %d\n", a[i].number, a[i].name, a[i].job, a[i].c.classes);
		}
	}
	printf("tcount = %d, wcount = %d",ct,cw);
	return 0;
}

(2)设计思路

首先需要定义一个结构体,因为结构体中要包含的第四项内容是需要分情况处理的,所以需要再定义一个共用体包含这两种情况,然后结构体的第四项类型就定义为所定义的共用体类型。
在输入的时候,应该先输入结构体前三项内容,然后判断第三项符合哪种情况,再输入第四项内容,分类计数符合情况即给每一类的数目加一。

(3)所遇问题

a.在输出的时候,后面的数据都没有输出来,显示结果均为0。
b.问题a修改后,发现第三项输出多了一个空格。

(4)解决方案

a.首先检查输入时是否存在问题,结果发现在读取job为’t’类型的第四项时出现问题,通过题中所给样例发现有的字符串中是存在空格的,将scanf("%s",)读入,改为gets()函数读入。
b.第三项读入后面应该加上空格,避免空格被gets()读入。

(5)终极代码

#include <stdio.h>
union Class
{
	int classes;
	char position[30];
};
struct Inf
{
	int number;
	char name[30];
	char job;
	union Class c;
}a[100];
int main(void)
{
	int n;
	int ct = 0, cw = 0;
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		scanf("%d %s %c ",&a[i].number,a[i].name,&a[i].job);
		if (a[i].job == 't')
		{
			gets(a[i].c.position);
			ct++;
		}
		else
		{
			scanf("%d", &a[i].c.classes);
			cw++;
		}
	}
	for (int i = 0; i < n; i++)
	{
		if (a[i].job == 't')
		{
			printf("%d %s %c %s\n",a[i].number,a[i].name,a[i].job,a[i].c.position);
		}
		else
		{
			printf("%d %s %c %d\n", a[i].number, a[i].name, a[i].job, a[i].c.classes);
		}
	}
	printf("tcount = %d, wcount = %d",ct,cw);
	return 0;
}

(四)寻找孪生素数

数学家希尔伯特在1900年国际数学家大会的报告上提出一个“孪生素数猜想”,即: 存在无穷多个素数p,使得p + 2是素数。p和p+2这一对差为2的素数,被称为“孪生素数”。
看起来,这个猜想是成立的,我们总能找到很多对孪生素数,例如:3和5,5和7,11和13…… 这一猜想至今还未被证明。
现在,对于给定的整数n, 请寻找大于n的最小的一对孪生素数p和q(q=p+2)。

输入格式:

一个不超过7位数字的整数n。

输出格式:

在一行中输出 p q ,中间用空格间隔。

输入样例:

100

输出样例:

101 103

(1)实验代码

#include<stdio.h>
int PRIME(int n)
{
	if(n<=1) return 0;
    for(int i=2;i<=(int)sqrt(n);i++)
    {
	    if(n%i==0)return 0;
	}
	return 1;
}
int main(void)
{
	int n;
	scanf("%d",&n);
	for(int i=n+1;;i++)
	{
	   if(PRIME(i)==1&&PRIME(i+2)==1)
	   {
	   	   printf("%d %d",i,i+2);
	   	   break;
	   }
	}
	return 0;
	
}

(2)设计思路

因为需要判断当前数和当前数+2的数是否为素数,所以写函数PRIME()用于判断素数。

(五)素数对猜想

让我们定义dn 为:dn=pn+1−pn,其中pi是第i个素数。显然有d​1=1,且对于n>1有d​n​​ 是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。

现给定任意正整数N(<10​5),请计算不超过N的满足猜想的素数对的个数。

输入格式:

输入在一行给出正整数N。

输出格式:

在一行中输出不超过N的满足猜想的素数对的个数。

输入样例:

20

输出样例:

4

(1)实验代码

#include<stdio.h>
#include<math.h>
int PRIME(int n)
{
	if(n<=0) return 0;
    for(int i=2;i<=(int)sqrt(n);i++)
    {
	    if(n%i==0)return 0;
	}
	return 1;
}
int main(void)
{
	int n,count=0;
	scanf("%d",&n);
	for(int i=2;i<=n;i++)
	{
	   if(PRIME(i)==1&&PRIME(i+2)==1)//问题
	   {
	   	   count++;
	   }
	}
	printf("%d",count);
	return 0;
	
}

(2)设计思路

这道题的设计思路同前面的那道题很像,需要改变for循环中的条件。

(3)所遇问题

测试样例中有一例“正好有一例跨界”,这个过不去。

(4)解决方案

跨界的那一例不应该计入总数中,所以在if的判断条件中应该在加上一条i+2<=n。

(5)终极代码

#include<stdio.h>
#include<math.h>
int SU(int n)
{
	if(n<=0) return 0;
    for(int i=2;i<=(int)sqrt(n);i++)
    {
	    if(n%i==0)return 0;
	}
	return 1;
}
int main(void)
{
	int n,count=0;
	scanf("%d",&n);
	for(int i=2;i<=n;i++)
	{
	   if(SU(i)==1&&SU(i+2)==1)
	   {
	   	   count++;
	   }
	}
	printf("%d",count);
	return 0;
	
}

(六)求矩阵不靠边元素之和

求矩阵的所有不靠边元素之和,矩阵行的值m从键盘读入(2<=m<=10),调用自定义函数Input实现矩阵元素从键盘输入,调用Sum函数实现求和。(只考虑float型,且不需考虑求和的结果可能超出float型能表示的范围)。

函数接口定义:

void Input (float a[][N], int m );
float Sum ( float a[][N], int m );
Input函数完成从键盘矩阵元素的功能, Sum函数完成求和并将结果返回。 m 代表矩阵的行。

裁判测试样例

#include<stdio.h>

#define M 10
#define N 4

void Input(float a[][N],int m);
float Sum(float a[][N],int m);


int main(void)
{
		float num[M][N],sum;
	
		int m;
		scanf("%d", &m);
		Input(num,m); 
	
		sum = Sum(num,m);
		printf("sum = %.2f\n", sum);
		return 0;
}
/* 请在这里填写答案 */

输入样例:

4
18 29.5 45 33
66 3.4 11.5 57
70 100 2 16.9
15 25.8 4.5 36

输出样例:

sum = 116.这里是引用

(1)实验代码

void Input(float a[][N], int m)
{
	for (int i = 0; i < m; i++)
	{
		for (int j = 0; j < N; j++)
		{
			scanf("%f", &a[i][j]);
		}
	}
}
float Sum(float a[][N], int m)
{
	float sum=0;
	for (int i = 1; i < m - 1; i++)
	{
		for (int j = 1; j < N - 1; j++)
		{
			sum += a[i][j];
		}
	}
	return sum;
}

(2)设计思路
使用两个for循环进行输入,在求和的时候把行和列都去掉首和尾,最后返回求和的结果就好啦!

(七)利用指针找最大值

本题要求实现一个简单函数,找出两个数中的最大值。

函数接口定义:

void findmax( int *px, int *py, int *pmax );
其中px和py是用户传入的两个整数的指针。函数findmax应找出两个指针所指向的整数中的最大值,存放在pmax指向的位置。

裁判测试程序样例:

#include <stdio.h>

void findmax( int *px, int *py, int *pmax );

int main()
{	
    int max, x, y; 

    scanf("%d %d", &x, &y);
    findmax( &x, &y, &max );
    printf("%d\n", max);

    return 0;
} 

/* 你的代码将被嵌在这里 */

输入样例:

3 5

输出样例:

5

(1)实验代码

void findmax(int* px, int* py, int* pmax)
{
    if (*px > * py)
    {
        *pmax = *px;
    }
    else
    {
        *pmax = *py;
    }
}

(2)设计思路
思路很简单的哦!之需要判断大小,然后把大的那一方的值赋给所给指针。

(八)在一个升序排列的数组中插入一个数

编写函数fun,在一个已按升序排列的数组中插入一个数,插入后,数组元素仍按升序排列。

函数接口定义:

void fun(int a[N],int number);
其中 a 和 number 都是用户传入的参数。函数在一个已按升序排列的数组 a 中插入一个数 number ,插入后,数组元素仍按升序排列

裁判测试程序样例:

#include <stdio.h>
#define N 11
void fun(int a[N],int number);
int main()
{
 int i,number,a[N]={1,2,4,6,8,9,12,15,149,156};
 scanf("%d",&number);
 printf("The original array:\n");
 for(i=0;i<N-1;i++)
    printf("%5d",a[i]);
 printf("\n");
 fun(a,number);
    printf("The result array:\n");
  for(i=0;i<N;i++)
     printf("%5d",a[i]);
 printf("\n");
 return 0;
 }

/* 请在这里填写答案 */

输入样例:

6

输出样例:

The original array:
1 2 4 6 8 9 12 15 149 156
The result array:
1 2 4 6 6 8 9 12 15 149 156

(1)实验代码

void fun(int a[N], int number)
{
    for (int i = N - 2; i >= 0; i--)
    {
        if (a[i] <= number)
            break;
        else
        {
            a[i+1] = a[i];
            a[i] = number;
        }
    }
}

(2)设计思路

利用for循环倒序判断,如果该数大于所给number则一直交换位置,直至该数小于number。

(九)递归求交错幂级数的和

本题要求实现一个函数,计算下列简单交错幂级数的部分和
f(x)=x-x²+x³-······pow((-1),n-1)pow(x,n)

函数接口定义:

double fn( double x, int n );
其中题目保证传入的n是正整数,并且输入输出都在双精度范围内。函数fn应返回上述级数的部分和。建议尝试用递归实现。

裁判测试程序样例:

#include <stdio.h>

double fn( double x, int n );

int main()
{
    double x;
    int n;

    scanf("%lf %d", &x, &n);
    printf("%.2f\n", fn(x,n));

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

0.5 12

输出样例:

0.33

(1)实验代码

double fn( double x, int n )
{
    double sum;
   if(n==0 ||n==1)
       sum=x;
   else
       sum=x-x*fn(x,n-1);
   return sum;
}

(2)设计思路
主要就在于sum=x-x*fn(x,n-1),使用这个式子对后面的每一项的系数和指数进行改变。

(十)逆序数据建立链表

本题要求实现一个函数,按输入数据的逆序建立一个链表。

函数接口定义:

struct ListNode *createlist();
函数createlist利用scanf从输入中获取一系列正整数,当读到−1时表示输入结束。按输入数据的逆序建立一个链表,并返回链表头指针。链表节点结构定义如下:

struct ListNode {
int data;
struct ListNode *next;
};
裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

struct ListNode {
    int data;
    struct ListNode *next;
};

struct ListNode *createlist();

int main()
{
    struct ListNode *p, *head = NULL;

    head = createlist();
    for ( p = head; p != NULL; p = p->next )
        printf("%d ", p->data);
    printf("\n");

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

1 2 3 4 5 6 7 -1

输出样例:

7 6 5 4 3 2 1

(1)实验代码

struct ListNode* createlist()
{
    struct ListNode* head,*p;
    int n;
    head= (struct ListNode*)malloc(sizeof(struct ListNode));
    head->next = NULL;
    scanf("%d", &n);
    while (n != -1)
    {
        p = (struct ListNode*)malloc(sizeof(struct ListNode));
        p->data = n;//将n存入结点p中
        p->next = head->next;;//确定p的位置
        head->next = p;//将head的位置进行移动,移动到p前面
        scanf("%d", &n);
    }
    return head->next;
}

我是鲤鲤,一只能带来好运的小鲤鱼。
如果你觉得以上对你有帮助,阔以点点左下角的👍吗?
♥就酱紫啦~byebye 大家一起努力,加油!!!
在这里插入图片描述

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值