(一)到底是不是太胖了
据说一个人的标准体重应该是其身高(单位:厘米)减去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个素数。显然有d1=1,且对于n>1有dn 是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。
现给定任意正整数N(<105),请计算不超过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 大家一起努力,加油!!!