目录
- 6-24 空间两点间的距离
- 6-25 还书有多难
- 6-26 计算两数的和与差
- 6-27 拆分实数的整数与小数部分
- 6-28 使用函数实现字符串部分复制
- 6-29 判断回文字符串
- 6-30 字符串的连接
- 6-31 指定位置输出字符串
- 6-32 利用指针找最大值
- 6-33 求一组数中的最大值、最小值和平均值
- 6-34 使用函数找出数组中的最大值
- 6-35 每个单词的首字母改为大写
- 6-36 输入单词并排序输出
- 6-37 分割单词并排序与唯一输出
- 6-38 二维数组求最大值
- 6-39 结构体数组中按关键字查找满足条件的数据节点
- 6-40 从结构体数组中查找指定信息的元素
- 6-41 调和平均 - 《C++编程基础及应用》
- 6-42 通过指针数组将由一维数组构成的二维数组进行按行及按列输出
- 6-43 学生平均成绩的计算和输出
- 6-44 时间换算
- 6-45 输入3个整数,按由小到大的顺序输出,编写一个函数,完成两个数字的交换
- 6-46 整数位移
- 6-47 结构体数组指针排序
6-24 空间两点间的距离
已知空间中两点A(x_1,y_1,z_1) 和 B(x_2,y_2,z_2) 之间的欧式距离为:
\sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2 + (z_1 - z_2)^2}
本题要求实现一个函数,计算平面上两点之间的欧氏距离,平面上点的坐标通过以下结构给出:
struct point {
double x, y, z;
};
函数接口定义:
// 计算并返回平面上两点 a 和 b 之间的欧氏距离
double distance(struct point a, struct point b);
裁判测试程序样例:
#include <stdio.h>
#include <math.h>
struct point {
double x, y, z;
};
void read_point(struct point *p);
double distance(struct point a, struct point b);
int main(void)
{
struct point p1, p2;
read_point(&p1);
read_point(&p2);
printf("%f\n", distance(p1, p2));
return 0;
}
void read_point(struct point *p)
{
scanf("%lf %lf %lf", &p->x, &p->y, &p->z);
}
/* 请在这里填写答案 */
输入样例:
在这里给出一组输入。例如:
0 0 0 3 0 4
输出样例:
在这里给出相应的输出。例如:
5.000000
// 计算并返回平面上两点 a 和 b 之间的欧氏距离
double distance(struct point a, struct point b){
return sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2)+pow(a.z-b.z,2));
}
6-25 还书有多难
某图书馆规定,一次借阅期限为60天,请编写函数计算借书日期与还书日期之间的天数。若还书日期早于借书日期,将返回-1。
程序将输入若干组数据进行测试,并输出每组的天数。题目保证所输入的日期均为有效日期。
函数接口定义:
int days(Date *d1,Date *d2);
这里的Date为表示日期的结构类型,定义如下:
typedef struct date{
int y,m,d;
}Date;
裁判测试程序样例:
#include <stdio.h>
typedef struct date{
int y,m,d;
}Date;
/* 请在这里填写答案 */
int main(){
int n;
scanf("%d",&n);
Date *borrow_date=(Date *)malloc(sizeof(Date));
Date *return_date=(Date *)malloc(sizeof(Date));
for(int i=1;i<=n;i++){
scanf("%d%d%d",&borrow_date->y,&borrow_date->m,&borrow_date->d);
scanf("%d%d%d",&return_date->y,&return_date->m,&return_date->d);
printf("%d\n",days(borrow_date,return_date));
}
free(borrow_date);
free(return_date);
return 0;
}
输入样例:
2
1999 12 10
2001 2 5
2000 12 20
2001 1 20
输出样例:
423
31
int isLeapYear(int x){
return ((x%4==0 && x%100!=0) || x%400==0)?1:0;
}
int days(Date *d1,Date *d2){
int monthes[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int s1=0,s2=0; // 总天数
for(int i=1;i<d1->y;i++) s1+=365+isLeapYear(i);
for(int i=1;i<d1->m;i++){
if(i==2) s1+=isLeapYear(d1->y); // !!!
s1+=monthes[i];
}
s1+=d1->d; // !!!
for(int i=1;i<d2->y;i++) s2+=365+isLeapYear(i);
for(int i=1;i<d2->m;i++){
if(i==2) s2+=isLeapYear(d2->y); // !!!
s2+=monthes[i];
}
s2+=d2->d; // !!!
return s2-s1>0?s2-s1:-1;
}
6-26 计算两数的和与差
本题要求实现一个计算输入的两数的和与差的简单函数。
函数接口定义:
void sum_diff( float op1, float op2, float *psum, float *pdiff );
其中op
1和op2
是输入的两个实数,*psum
和*pdiff
是计算得出的和与差。
裁判测试程序样例:
#include <stdio.h>
void sum_diff( float op1, float op2, float *psum, float *pdiff );
int main()
{
float a, b, sum, diff;
scanf("%f %f", &a, &b);
sum_diff(a, b, &sum, &diff);
printf("The sum is %.2f\nThe diff is %.2f\n", sum, diff);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
4 6
输出样例:
The sum is 10.00
The diff is -2.00
void sum_diff( float op1, float op2, float *psum, float *pdiff ){
*psum=op1+op2;
*pdiff=op1-op2;
}
6-27 拆分实数的整数与小数部分
本题要求实现一个拆分实数的整数与小数部分的简单函数。
函数接口定义:
void splitfloat( float x, int *intpart, float *fracpart );
其中x
是被拆分的实数(0≤x
<10000),*intpart
和*fracpart
分别是将实数x拆分出来的整数部分与小数部分。
裁判测试程序样例:
#include <stdio.h>
void splitfloat( float x, int *intpart, float *fracpart );
int main()
{
float x, fracpart;
int intpart;
scanf("%f", &x);
splitfloat(x, &intpart, &fracpart);
printf("The integer part is %d\n", intpart);
printf("The fractional part is %g\n", fracpart);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
2.718
输出样例:
The integer part is 2
The fractional part is 0.718
void splitfloat( float x, int *intpart, float *fracpart ){
*intpart=(int)x;
*fracpart=x-*intpart;
}
6-28 使用函数实现字符串部分复制
本题要求编写函数,将输入字符串t中从第m个字符开始的全部字符复制到字符串s中。
函数接口定义:
void strmcpy( char *t, int m, char *s );
函数strmcpy
将输入字符串char *t
中从第m
个字符开始的全部字符复制到字符串char *s
中。若m
超过输入字符串的长度,则结果字符串应为空串。
裁判测试程序样例:
#include <stdio.h>
#define MAXN 20
void strmcpy( char *t, int m, char *s );
void ReadString( char s[] ); /* 由裁判实现,略去不表 */
int main()
{
char t[MAXN], s[MAXN];
int m;
scanf("%d\n", &m);
ReadString(t);
strmcpy( t, m, s );
printf("%s\n", s);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
7
happy new year
输出样例:
new year
// 若m超过输入字符串的长度,则结果字符串应为空串
// 方法一
void strmcpy( char *t, int m, char *s ){
t=t+m-1;
while(*t!='\0'){
*s=*t;
t++;
s++;
}
*s='\0';
}
// 方法二
void strmcpy( char *t, int m, char *s ){
memset(s,0,sizeof(s));
int len=strlen(t);
if(m>len) *s=NULL;
else{
int cnt=0;
for(int i=m-1;i<len;i++) s[cnt++]=t[i];
s[cnt]='\0';
}
}
6-29 判断回文字符串
本题要求编写函数,判断给定的一串字符是否为“回文”。所谓“回文”是指顺读和倒读都一样的字符串。如“XYZYX”和“xyzzyx”都是回文。
函数接口定义:
bool palindrome( char *s );
函数palindrome
判断输入字符串char *s
是否为回文。若是则返回true
,否则返回false
裁判测试程序样例:
#include <stdio.h>
#include <string.h>
#define MAXN 20
typedef enum {false, true} bool;
bool palindrome( char *s );
int main()
{
char s[MAXN];
scanf("%s", s);
if ( palindrome(s)==true )
printf("Yes\n");
else
printf("No\n");
printf("%s\n", s);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例1:
thisistrueurtsisiht
输出样例1:
Yes
thisistrueurtsisiht
输入样例2:
thisisnottrue
输出样例2:
No
thisisnottrue
bool palindrome( char *s ){
int l=0,r=strlen(s)-1;
while(l<r){
if(s[l++]!=s[r--]) return false;
}
return true;
}
6-30 字符串的连接
本题要求实现一个函数,将两个字符串连接起来。
函数接口定义:
char *str_cat( char *s, char *t );
函数str_cat
应将字符串t
复制到字符串s
的末端,并且返回字符串s
的首地址。
裁判测试程序样例:
#include <stdio.h>
#include <string.h>
#define MAXS 10
char *str_cat( char *s, char *t );
int main()
{
char *p;
char str1[MAXS+MAXS] = {'\0'}, str2[MAXS] = {'\0'};
scanf("%s%s", str1, str2);
p = str_cat(str1, str2);
printf("%s\n%s\n", p, str1);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
abc
def
输出样例:
abcdef
abcdef
char *str_cat( char *s, char *t ){
int len=strlen(s);
for(int i=0;t[i]!='\0';i++){
s[len++]=t[i];
}
s[len]='\0';
return s;
}
6-31 指定位置输出字符串
本题要求实现一个函数,对给定的一个字符串和两个字符,打印出给定字符串中从与第一个字符匹配的位置开始到与第二个字符匹配的位置之间的所有字符。
函数接口定义:
char *match( char *s, char ch1, char ch2 );
函数match
应打印s
中从ch1
到ch2
之间的所有字符,并且返回ch1
的地址。
裁判测试程序样例:
#include <stdio.h>
#define MAXS 10
char *match( char *s, char ch1, char ch2 );
int main()
{
char str[MAXS], ch_start, ch_end, *p;
scanf("%s\n", str);
scanf("%c %c", &ch_start, &ch_end);
p = match(str, ch_start, ch_end);
printf("%s\n", p);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例1:
program
r g
输出样例1:
rog
rogram
输入样例2:
program
z o
输出样例2:
(空行)
(空行)
输入样例3:
program
g z
输出样例3:
gram
gram
char *match( char *s, char ch1, char ch2 ){
for(int i=0;s[i]!='\0';i++){
if(s[i]==ch1){ // 与第一个字符匹配
for(int j=i;s[j]!='\0';j++){
printf("%c",s[j]);
if(s[j]==ch2) break;
}
printf("\n");
return s+i;
}
}
printf("\n");
return s+strlen(s);
}
6-32 利用指针找最大值
本题要求实现一个简单函数,找出两个数中的最大值。
函数接口定义:
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
void findmax( int *px, int *py, int *pmax ){
*pmax=(*px>*py?*px:*py);
}
6-33 求一组数中的最大值、最小值和平均值
编写函数,求一组数中的最大值、最小值和平均值。
函数接口定义:
float fun(int a[],int n,int *max,int *min);
其中 a
、n
、max
和 min
都是用户传入的参数。函数求a
数组中n
个元素的最大值、最小值和平均值。最大值和最小值分别通过max
和 min
带回,函数返回平均值 。
裁判测试程序样例:
#include <stdio.h>
float fun(int a[],int n,int *max,int *min);
int main()
{
int x[10],i,m,n;
float p;
for(i=0;i<10;i++)
scanf("%d",&x[i]);
p=fun(x,10,&m,&n);
printf("max=%d,min=%d,average=%.2f\n",m,n,p);
return 0;
}
/* 请在这里填写答案 */
输入样例:
2 5 4 8 6 9 1 3 7 0
输出样例:
max=9,min=0,average=4.50
float fun(int a[],int n,int *max,int *min){
double sum=0;
*max=-1,*min=999999;
for(int i=0;i<n;i++){
if(a[i]>*max) *max=a[i];
if(a[i]<*min) *min=a[i];
sum+=a[i];
}
return sum/n;
}
6-34 使用函数找出数组中的最大值
本题要求实现一个找出整型数组中最大值的函数。
函数接口定义:
int FindArrayMax( int a[], int n );
其中a
是用户传入的数组,n
是数组a
中元素的个数。函数返回数组a
中的最大值。
裁判测试程序样例:
#include <stdio.h>
#define MAXN 10
int FindArrayMax( int a[], int n );
int main()
{
int i, n;
int a[MAXN];
scanf("%d", &n);
for( i=0; i<n; i++ ){
scanf("%d", &a[i]);
}
printf("%d\n", FindArrayMax(a, n));
return 0;
}
/* 请在这里填写答案 */
输入样例:
4
20 78 99 -14
输出样例:
99
int FindArrayMax( int a[], int n ){
int max=a[0];
for(int i=1;i<n;i++){
if(a[i]>max) max=a[i];
}
return max;
}
6-35 每个单词的首字母改为大写
本题要求实现一个函数,将p所指字符串中每个单词的首字母字母改成大写,大写字母及非字母不变化。(这里的“单词”是指由一个或者多个空格隔开的字符串)。
函数接口定义:
void Conv( char *p );
其中 p
是用户传入的参数,函数将 p 所指字符串中每个单词的首字母改成大写。
裁判测试程序样例:
#include <stdio.h>
void Conv( char *p );
int main()
{
char str[64];
gets(str);
Conv(str);
printf("After changing: %s", str);
return 0;
}
/* 请在这里填写答案 */
输入样例1:
i am a student.
输出样例1:
After changing: I Am A Student.
输入样例2:
There are 45 students in my class.
输出样例2:
After changing: There Are 45 Students In My Class.
#include <ctype.h>
void Conv( char *p ){
for(int i=0;p[i]!='\0';i++){
if(i==0 && islower(p[i])){
p[i]-=32;
}
if(isspace(p[i]) && islower(p[i+1])){
p[i+1]-=32;
}
}
}
6-36 输入单词并排序输出
本题要求通过input()函数实现输入若干个单词(每单词的长度不超过20,单词的最大数目不超过10)。输入过程中遇到单词END 则提前结束输入(END不作为后面排序的单词),或单词数目达到10个也结束。然后调用函数paixu(),对这若干个单词按字典顺序进行排序,最后调用函数printArr()输出排序后的单词,输出的单词之间以空格进行分隔,最后一个单词后面没有空格。
函数接口定义:
int input(char ar2[][21]);
其中函数的返回值等于输入的有效单词的数目。
void paixu(char ar2[][21], int n);
其中函数完成对ar2数组中的n个字符串进行排序。
void printArr(char ar2[][21], int n);
其中函数完成对ar2数组中的n个字符串进行输出。
裁判测试程序样例:
#include<stdio.h>
#include<string.h>
int input(char ar2[][21]);
void paixu(char ar2[][21], int n);
void printArr(char ar2[][21], int n);
int main(void)
{
char arr[10][21]={0};
int n;
n=input(arr);
paixu(arr,n);
printArr(arr,n);
return 0;
}
/* 请在这里填写答案 */
输入样例:
China Britain America Japan Egypt END
输出样例:
After sorted:
America Britain China Egypt Japan
输入样例:
END
输出样例:
NO WORD
输入样例:
a1 b2 c3 d4 e5 a6 b7 c8 d9 e10 a11 b12 c13
输出样例:
After sorted:
a1 a6 b2 b7 c3 c8 d4 d9 e10 e5
int input(char ar2[][21]) // 其中函数的返回值等于输入的有效单词的数目。
{
int cnt = 0;
while(cnt<10 && scanf("%s",ar2[cnt])){
// scanf("%s",&ar2[cnt]);
if( strcmp(ar2[cnt],"*END*")==0 )
break;
cnt++;
}
return cnt; // 实际长度
}
// 其中函数完成对ar2数组中的n个字符串进行排序。
void paixu(char ar2[][21], int n)
{
// 冒泡排序
for(int i=0;i<n-1;i++) // n-1趟
{
for(int j=0;j<n-i-1;j++) // 第i趟有n-i-1对
{
if( strcmp(ar2[j],ar2[j+1]) >0 )
{
char temp[21];
strcpy(temp,ar2[j]);
strcpy(ar2[j],ar2[j+1]);
strcpy(ar2[j+1],temp);
}
}
}
}
// 其中函数完成对ar2数组中的n个字符串进行
void printArr(char ar2[][21], int n) 输出。
{
if(n==0)
printf("NO WORD");
else{
printf("After sorted:\n");
for(int i=0;i<n;i++){
if(i>0) printf(" ");
printf("%s",ar2[i]);
}
}
}
6-37 分割单词并排序与唯一输出
程序的功能:先利用MyGets()函数输入一个字符串存到数组arr1中(输入过程中,若输入空格与大小字母以外的字符,则为无效字符,不放入数组;输入过程中遇到回车则结束输入),利用puts()函数输出只含有效字符的字符串,然后调用split_sort()函数把一维数组ar1中用一个或多个空格分割的单词取出并按升序排序输出(输出的单词若相同,则只输出一个,单词之间以字符’*'分割)。
函数接口定义:
void MyGets(char ar1[],int n); //读取字符数据,只留下空格与字母,并以字符串的形式存放到一维数组ar1中,n为数组ar1的宽度
void split_sort(char ar1[]); //将一维数组ar1中用一个或多个空格分割的单词取出并按升序排序输出(相同单词只输出一个,单词之间以字符'*'分割)
裁判测试程序样例:
#include<stdio.h>
#include<string.h>
void MyGets(char ar1[],int n);
void split_sort(char ar1[]);
int main(void)
{
char arr1[100]={0};
int i,wordNum;
MyGets(arr1,100);
printf("Valid string:\n");
puts(arr1);
printf("Sorted words:\n");
split_sort(arr1);
return 0;
}
/* 请在这里填写答案 /
输入样例1:
1:China 2:America 3:Germany 4:Japan 5:Egypt
输出样例1:
Valid string:
China America Germany Japan Egypt
Sorted words:
AmericaChinaEgyptGermany*Japan
输入样例2:
3d 343 d34 345 vcd 3zdc vcd
输出样例2:
Valid string:
d d vcd zdc vcd
Sorted words:
d*vcd*zdc
//用gets()函数可以把回车之前输入的字符全部读入,满足到回车结束的条件;
//a[i] != '\0' && i < n - 1 ,满足数组读满则结束和未满则有效字符全部读入的要求
void MyGets(char ar1[],int n)
{
char a[1000], ch;
int cnt = 0;
gets(a);
for(int i = 0; a[i]!='\0' && i < n - 1; i++)
{
ch = a[i];
if(ch == ' ' || (ch >= 'a'&& ch <= 'z') ||(ch >= 'A'&& ch <= 'Z'))
{
ar1[cnt] = ch;
cnt++;
}
}
}
void split_sort(char ar1[]){
char w[100][30]; //存放被分离出的每个单词的数组
int i = 0, j = 0 , n = 0;
int flag = 0;
for(i = 0; ar1[i] != '\0'; i++)
{
if(ar1[i] != ' ')
{
w[n][j] = ar1[i];
j++;
flag = 1; //表示第一个单词已经查找到
}
if(ar1[i]==' ' && flag != 0){ //设置条件flag != 0,则开头的空格就不会被存进数组,节约空间
w[n][j] = '\0';
j = 0;
n++;
}
}
w[n][j] = '\0';
//逐个比较,如果有两个相同的字符串,就把后一个改为空串。
for(i = 0; i < n ; i++){
for(j = i + 1; j< n + 1; j++)
{
if(strcmp(w[i],w[j]) == 0 )
strcpy(w[j],"\0");
}
}
//比较,调整为升序
char t[100];
for(i = 0; i < n; i++)
for(j = i + 1; j < n + 1; j++)
if(strcmp(w[i],w[j])>0) // strcmp(a,b)>0即a>b
{
strcpy(t,w[i]);
strcpy(w[i],w[j]);
strcpy(w[j],t);
}
//空串一律不输出,注意输出格式
flag=1;
for(i = 0;i <n+1;i++)
{
if(w[i][0]!='\0'){
if(flag)
printf("%s", w[i]),flag=0;
else
printf("*%s", w[i]);
}
}
}
6-38 二维数组求最大值
二维数组:求最大元素。求出n×m(1<=n,m<=N=20)整型数组的最大元素
函数接口定义:
int fun(int array[][N],int n,int m) ;
在这里解释接口参数。例如:其中 array[][N]
是待求最大值得二维数组, n
是二维数组的行数, m
是二维数组的列数。函数须返回 二维数组的最大值。
裁判测试程序样例:
#include <iostream>
using namespace std;
const int N=10;
int fun(int array[][N],int n,int m) ;
main()
{
int a[N][N],n,m,i,j,max;
cin>>n>>m;
for(i=0;i<n;i++)
for(j=0;j<m;j++)
cin>>a[i][j];
max=fun(a,n,m);
cout<<max;
}
/* 请在这里填写答案 */
输入样例:
在这里给出一组输入。例如:
1 10 2
3 12 5
4 11 3
5 12 4
输出样例:
在这里给出相应的输出。例如:
12
int fun(int array[][N],int n,int m) {
int max=-1;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++) {
if(array[i][j]>max) max=array[i][j];
}
}
return max;
}
6-39 结构体数组中按关键字查找满足条件的数据节点
struct student{
int num ;
char name[20];
int score;};
typedef struct student stu;
有上面面学生记录类型定义,
定义函数在一组学生记录中找成绩最低的学生信息,
最低分唯一
函数接口定义:
stu fun( stu a[] )
数组a里存储N个学生记录,返回值是最低分记录
裁判测试程序样例:
#include <stdio.h>
#define N 10
stu fun( stu a[] );
int main()
{
stu a[N], min;
int i;
for (i=0;i<N;i++)
scanf("%d%s%d",&a[i].num,a[i].name,&a[i].score);
min=fun(a);
printf("%d %s %d",min.num,,min.name,min.score);
}
/* 请在这里填写答案 */
输入样例:
在这里给出一组输入。例如:
1 a01 62
2 a02 56
3 a03 77
4 aaa 66
5 bbb 78
11 a01 62
12 a02 57
13 a03 77
14 aaa 96
15 bbb 78
输出样例:
在这里给出相应的输出。例如:
2 a02 56
stu fun( stu a[] ){
int min=101,min_index=0;
for(int i=0;i<N;i++){
if(a[i].score<min) {
min=a[i].score;
min_index=i;
}
}
return a[min_index];
}
6-40 从结构体数组中查找指定信息的元素
本题要求实现一个函数,可从一个结构体数组data
域中查找一个给定的数据元素x
,查找成功,返回该元素所在位置的指针;否则,返回NULL
。
函数接口定义:
INFO *SearchIn ( INFO *p, int n, int x );
其中 p
、n
和 x
都是用户传入的参数。 p
是一个INFO
类型的指针;n
是数组元素个数, x
是要查找的数据元素。函数返回 x
在 p
所指的数组中具体位置。
裁判测试程序样例:
#include <stdio.h>
typedef struct _INFO {
int data;
char name[20];
} INFO;
INFO *SearchIn ( INFO *p, int n, int x );
int main()
{
int i, n, x;
INFO info[10], *p;
scanf("%d", &n);
for (i = 0; i < n; i++)
scanf("%d %s", &info[i].data, info[i].name);
scanf("%d", &x);
p = SearchIn ( info, n, x );
if (p != NULL)
printf("%s %d\n", p->name, p->data);
else
printf("Not Found!\n");
return 0;
}
输入样例1:
3
351 Windows
278 iOS
224 Andriod
278
输出样例1:
iOS 278
输入样例2:
3
351 Windows
278 iOS
224 Andriod
235
输出样例2:
Not Found!
INFO *SearchIn ( INFO *p, int n, int x ){
for(int i=0;i<n;i++){
if(p[i].data==x) return &p[i]; //查找成功,返回该元素所在位置的指针
}
return NULL;
}
6-41 调和平均 - 《C++编程基础及应用》
函数hmean()用于计算整数x和y的调和平均数,结果应保存在指针r所指向的浮点数对象中。当x+y等于0时,函数返回0表示无法计算,否则返回1
。数学上,两个数x和y的调和平均数 z = 2xy/(x+y) 。
函数接口定义:
int hmean(const int x, const int y, float* r);
裁判测试程序样例:
#include <stdio.h>
hmean()函数定义处
int main()
{
int x=0,y=0;
scanf("%d %d",&x,&y);
float r = 0;
int b = hmean(x,y,&r);
if (b)
printf("hmean(%d,%d)=%.2f",x,y,r);
else
printf("Input error.");
return 0;
}
输入样例:
3 2
输出样例:
hmean(3,2)=2.40
int hmean(const int x, const int y, float* r){
*r=2.0*x*y/(x+y);
if(x+y==0) return 0;
else return 1;
}
6-42 通过指针数组将由一维数组构成的二维数组进行按行及按列输出
通过指针数组p和一维数组a构成一个3×4 的二维数组,并为a数组赋初值2、4、6、8、…。
要求:
1、先按行的顺序输出此"二维数组",每个元素占5个字符位置,每一行元素输出结束换行。
2、再按列的顺序输出它,每个元素占5个字符位置,每一列元素输出结束换行。
函数接口定义:
void input(int *p,int n);
//输入一维数组的值
void init(int *p,int **p1,int m,int n);
//初始化指针数组
void output1(int **p,int m,int n);
//按行输出
void output2(int **p,int m,int n);
//按列输出
裁判测试程序样例:
#include<stdio.h>
#define M 3
#define N 4
void input(int *p,int n);
//输入一维数组的值
void init(int *p,int **p1,int m,int n);
//初始化指针数组
void output1(int **p,int m,int n);
//按行输出
void output2(int **p,int m,int n);
//按列输出
int main()
{
int *p[M];
int a[M*N];
input(a,M*N);
init(a,p,M,N);
puts("按行输出:");
output1(p,M,N);
puts("按列输出:");
output2(p,M,N);
return 0;
}
/* 请在这里填写答案 */
输入样例:
在这里给出一组输入。例如:
2 4 6 8
10 12 14 16
18 20 22 24
输出样例:
在这里给出相应的输出。例如:
按行输出:
2 4 6 8
10 12 14 16
18 20 22 24
按列输出:
2 10 18
4 12 20
6 14 22
8 16 24
void input(int *p, int n) {
for (int i = 0; i < n; ++i) {
scanf("%d", &p[i]);
}
}
// 将一维数组变成二维数组
void init(int *p, int **p1, int m, int n) {
for (int i = 0; i < m; ++i) {
p1[i] = p + i * n;
}
}
void output1(int **p, int m, int n) {
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
printf("%5d", p[i][j]);
}
printf("\n");
}
}
void output2(int **p, int m, int n) {
for (int j = 0; j < n; ++j) {
for (int i = 0; i < m; ++i) {
printf("%5d", p[i][j]);
}
printf("\n");
}
}
6-43 学生平均成绩的计算和输出
本题要求实现一个函数,计算学生平均成绩并输出。要求:输入m个学生(0<m≤30)n门课程(0<n≤ 5)的成绩,然后调用函数计算并输出每个学生各门课的平均分。
函数接口定义:
void Score_Avg(int (*p)[N], int m, int n);
其中:p
为指向学生成绩数组的指针,m
和n
依次是学生人数、课程数。
裁判测试程序样例:
#include <stdio.h>
#define M 30
#define N 5
void Score_Avg(int (*p)[N], int m, int n);
int main()
{
int score[M][N], m, n, i, j;
scanf("%d%d", &m, &n); //输入学生数和课程数
for(i = 0; i<m; i++)
for(j = 0; j<n; j++)
scanf("%d", &score[i][j]);
Score_Avg(score, m, n); //计算并输出学生平均分
return 0;
}
/* 你的代码将被嵌在这里 */
输入格式:
学生数m 课程数n
学生1课程1分数 学生1课程2分数 … 学生1课程n分数
学生2课程1分数 学生2课程2分数 … 学生2课程n分数
.……
学生m课程1分数 学生m课程2分数 … 学生m课程n分数
输出格式:
学生1的平均分(实数,保留1位小数。下同)
学生2的平均分
.……
学生m的平均分
输入样例:
2 3
61 62 70
75 82 90
输出样例:
64.3
82.3
void Score_Avg(int (*p)[N], int m, int n){
for(int i=0;i<m;i++){
double sum=0;
for(int j=0;j<n;j++){
sum+=p[i][j];
}
printf("%.1f\n",sum/n);
}
}
6-44 时间换算
本题要求实现一个函数,计算以hh:mm:ss
的格式给出的时间再过n
(n≤60)秒后的时间值(超过23:59:59就从0点开始计时)。
时间结构体定义如下:
struct time
{
int h, m, s;
};
函数接口定义:
struct time timecov(struct time t, int n);
其中t
和n
分别是用户传入的待换算时间和换算秒数;函数timecov计算并返回
给定时间t再过n秒后的时间值。
裁判测试程序样例:
#include <stdio.h>
struct time
{
int h, m, s;
};
struct time timecov(struct time t, int n);
int main()
{
struct time t;
int n;
scanf("%d:%d:%d", &t.h, &t.m, &t.s);
scanf("%d", &n);
t = timecov(t, n);
printf("%02d:%02d:%02d\n", t.h, t.m, t.s);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
11:59:40
30
输出样例:
12:00:10
struct time timecov(struct time t, int n){
int totals=t.h*3600+t.m*60+t.s+n;
t.h=(totals/3600) % 24;
t.m=(totals/60) % 60;
t.s=totals%60;
return t;
}
6-45 输入3个整数,按由小到大的顺序输出,编写一个函数,完成两个数字的交换
输入3个整数,按由小到大的顺序输出,编写一个函数,完成两个数字的交换。
函数接口定义:
void swap(int *p1,int *p2);
*p1和*p2接收主函数传递的实参,函数swap()完成两个数字的交换。
裁判测试程序样例:
#include "stdio.h"
void swap(int *p1,int *p2);
int main()
{
int a1,a2,a3;
int *p1,*p2,*p3;
scanf("%d%d%d",&a1,&a2,&a3);
p1=&a1;
p2=&a2;
p3=&a3;
if (a1>a2) swap(p1,p2);
if (a1>a3) swap(p1,p3);
if (a2>a3) swap(p2,p3);
printf("%d < %d < %d",a1,a2,a3);
return 0;
}
/* 请在这里填写答案 */
输入样例:
在这里给出一组输入。例如:
3 -1 8
输出样例:
在这里给出相应的输出。例如:
-1 < 3 < 8
void swap(int *p1,int *p2){
int* temp=*p1;
*p1=*p2;
*p2=temp;
}
6-46 整数位移
整数交换
本题要求实现一个函数,可交换4个整数的位置,要求所有整数往后移动一位,最后一位往后移动就成为该组数据的第一位。具体请查看输入输出样例。
函数接口定义:
void Swap ( int *a, int *b, int *c, int *d );
裁判测试程序样例:
#include <stdio.h>
void Swap ( int *p, int *q, int *s, int *t );
int main()
{
int a, b, c, d;
scanf("%d %d %d %d", &a, &b, &c, &d);
Swap(&a, &b, &c, &d);
printf("%d %d %d %d", a, b, c, d);
return 0;
}
/* 请在这里填写答案 */
输入样例:
10 2 3 4
输出样例:
4 10 2 3
void Swap ( int *a, int *b, int *c, int *d ){
int* temp= *d;
*d=*c;
*c=*b;
*b=*a;
*a=temp;
}
6-47 结构体数组指针排序
某中学期末考试共有5门课程,需要录入每个学生5门课程的成绩,并计算每个学生每门课程成绩的排名,并输出成绩和排名信息。为完成该任务,表示学生课程成绩和排名的成绩记录结构体定义如下:
struct Student
{
int number; //学号
char name[10]; //姓名
int score[5]; //5门课程成绩
int rank[5]; //5门课程排名
};
指针数组排序函数如下:
函数接口定义:
按课程which的成绩从大到小排序
void SortStudentPtr(struct Student* arrStuPtr[], int n, int which);
其中 arrStuPtr 是用户传入的指向所有学生成绩记录的指针数组。 n 的表示学生的个数; which 是[0, 4]区间的整数,表示第几门课程。
裁判测试程序样例:
#include <stdio.h>
struct Student
{
int number; //学号
char name[10]; //姓名
int score[5]; //5门课程成绩
int rank[5]; //5门课程排名
};
void SortStudentPtr(struct Student* arrStuPtr[], int n, int which);
int main()
{
int i, c;
struct Student arrStu[10] = {
{1001, "zhangsan", 95, 84, 64, 75, 75},
{1002, "lisi", 87, 82, 82, 85, 76},
{1003, "wangwu", 92, 93, 73, 65, 93},
{1004, "zhaoliu", 90, 91, 89, 92, 87},
{1005, "sunqian", 85, 82, 86, 81, 85},
{1006, "wuge", 78, 74, 92, 79, 83},
{1007, "yaoyuan", 91, 69, 68, 83, 78},
{1008, "zhenghao", 67, 61, 71, 93, 86},
{1009, "guojing", 78, 72, 78, 95, 67},
{1010, "daigao", 80, 87, 88, 76, 96}
};
struct Student* arrStuPtr[10];
for (i = 0; i < 10; i++)
arrStuPtr[i] = arrStu + i;
for (c = 0; c < 5; c++)
{
SortStudentPtr(arrStuPtr, 10, c);
for (i = 0; i < 10; i++)
arrStuPtr[i]->rank[c] = i + 1;
}
printf("number\t name \tscore1\trank1\tscore2\trank2\tscore3\trank3\tscore4\trank4\tscore5\trank5\n");
for (i = 0; i < 10; i++)
{
printf("%d\t%10s\t", arrStu[i].number, arrStu[i].name);
for (c = 0; c < 5; c++)
printf("%d\t%d\t", arrStu[i].score[c], arrStu[i].rank[c]);
printf("\n");
}
return 0;
}
/* 请在这里填写答案 */
输入样例:
无
输出样例:
number name score1 rank1 score2 rank2 score3 rank3 score4 rank4 score5 rank5
1001 zhangsan 95 1 84 4 64 10 75 9 75 9
1002 lisi 87 5 82 5 82 5 85 4 76 8
1003 wangwu 92 2 93 1 73 7 65 10 93 2
1004 zhaoliu 90 4 91 2 89 2 92 3 87 3
1005 sunqian 85 6 82 6 86 4 81 6 85 5
1006 wuge 78 9 74 7 92 1 79 7 83 6
1007 yaoyuan 91 3 69 9 68 9 83 5 78 7
1008 zhenghao 67 10 61 10 71 8 93 2 86 4
1009 guojing 78 8 72 8 78 6 95 1 67 10
1010 daigao 80 7 87 3 88 3 76 8 96 1
void SortStudentPtr(struct Student* arrStuPtr[], int n, int which)
{
// 1.冒泡排序
for (int i = 0; i < n - 1; i++) {
// 内层循环,每一趟冒泡将最大的元素移到末尾
for (int j = 0; j < n - i - 1; j++) {
if (arrStuPtr[j]->score[which] <= arrStuPtr[j + 1]->score[which]) {
// 如果前面的元素大于后面的元素,交换它们的编号
struct Student* temp = arrStuPtr[j];
arrStuPtr[j] = arrStuPtr[j + 1];
arrStuPtr[j + 1] = temp;
}
}
}
void SortStudentPtr(struct Student* arrStuPtr[], int n, int which)
{
// 2.选择排序
for(int i=0;i<n-1;i++){
int x=i;
for(int j=i+1;j<n;j++){
if(arrStuPtr[x]->score[which] < arrStuPtr[j]->score[which]) x=j;
}
struct Student* temp=arrStuPtr[i];
arrStuPtr[i]=arrStuPtr[x];
arrStuPtr[x]=temp;
}
}