【C语言】期末复习专题——函数与指针习题

目录

前言:

函数

1.字符移动

函数接口定义:

裁判测试程序样例:

输入样例:

输出样例:

 做题时可能遇见的困难

 解决办法

 源代码

2. 确定进制

题目描述

输入

输出

样例输入 

样例输出 

 做题时可能遇见的困难

 源代码

3.猴子吃桃(船新版本)

题目描述

函数接口定义:

裁判测试程序样例:

输入样例:

输出样例:

 源代码

 指针

1.数组指针作函数参数

题目描述

输入格式:

输出格式:

输入样例:

输出样例:

 源代码

 2.报数

题目描述

输入样例:

输出样例:

 题目难点

 解决方案

 源代码

结尾:


前言:

临近期末,大家一起复习专题,逐个突破吧!!!

函数

1.字符移动

本题要求实现一个函数,对输入的英文字母和移动距离进行移动。例如输入:X 4,输出 B,输入a 30, 输出 e;

函数接口定义:
函数接口与定义: char move(char ch,int n);

例如:其中 ch 和 n 都是用户传入的参数。 ch的值为‘A’~’Z’或者’a’~’z’; n的值不超过int范围。函数须返回字符移动后的值。

裁判测试程序样例:
在这里给出函数被调用进行测试的例子。
例如: #include <stdio.h>
 int main()
 { char ch;
   int n;
   scanf("%c%d", &ch, &n);
   printf("%c", move(ch,n)); 
   return 0;
 } 
/* 请在这里填写答案 */
输入样例:

在这里给出一组输入。例如:

X 10
输出样例:

在这里给出相应的输出。例如:

H
 做题时可能遇见的困难

如果只是简单的加减,那超出字母范围的那部分如何处理

 解决办法

多出来的那部分取模26处理

 源代码
char move(char ch,int n)
{
    if(isupper(ch))
    {
        ch=(ch-'A'+n)%26+'A';//重点是做取模处理
    }
    else
        ch=(ch-'a'+n)%26+'a';
	return ch;
}

2. 确定进制

题目描述

6×9=42对于十进制来说是错误的,但是对于13进制来说是正确的。即, 6(13)× 9(13)= 42(13), 而 42(13)=4×131+2×130=54(10)。

你的任务是写一段程序,读入三个整数p、q和 r,然后确定一个进制 B(2<=B<=40) 使得 p × q = r。 如果 B 有很多选择, 输出最小的一个。

例如:p=11, q=11, r=121.则有11(3)× 11(3)= 121(3)因为 11(3)= 1 × 31+ 1 × 30= 4(10)和121(3)=1×32+2×31+1×30=16(10)。对于进制 10,同样有11(10)× 11(10)= 121(10)。这种情况下,应该输出 3。如果没有合适的进制,则输出 0。

输入

一行,包含三个整数p、q、r。 p、q、r的所有位都是数字,并且1 ≤ p、q、r ≤ 1,000,000。

输出

一个整数:即使得p×q=r成立的最小的B。如果没有合适的B,则输出0。

样例输入 
6 9 42
样例输出 
13
 做题时可能遇见的困难

 1.如何将十进制变成任意进制

2.如何确定最小的B

 源代码
#include<stdio.h>
int jinzhi(int *arr)
{
    int i,k,l;
  	int a=0;
    for(i=2;i<=40;i++)
    {
    	int brr[3]={0};//用数组储存这三个数通过进制转换后的值,并且若不相等,可以重新更新
        for(k=0;k<3;k++)
        {
        int t=arr[k];
        int l=1;
        if(arr[k]<i)//如果数小于进制的话,就不需要转换
        {
        	brr[k]=arr[k];
        	continue;
		}
		else
        while(t)//令数一位一位的变化
        {
            brr[k]+=t%10*l;
            t/=10;
            l*=i;
        }
        }
        if(brr[0]*brr[1]==brr[2])//进行判断,若相等就退出,这样就可以确定返回的是最小的进制
        {
            a=i;
            break;
        }
    }
    return a;
}
int main()
{
    int p,q,r;
    scanf("%d %d %d",&p,&q,&r);
    int arr[3];
    arr[0]=p;arr[1]=q;arr[2]=r;
    int end;
    end=jinzhi(arr);//这里我采用数组存储,可以一次性将全部数传入到函数中
    printf("%d",end);
}

3.猴子吃桃(船新版本)

提到函数怎么可能没有递归,我之前也发过递归的两篇文章,而这个题跟之前的猴子吃桃很像,但是有一定的改变,所以拿出来说说,绝对不是我想水题目

之前递归的链接:

算法:递归(1)-CSDN博客

算法:递归(2)-CSDN博客

题目描述

小猴子第一天摘下桃子若干,当即吃掉一半,还不过瘾,又多吃一个,第二天又将剩下的桃子吃掉一半多一个,以后每天吃掉前一天剩下的一半多一个,到第n天准备吃的时候只剩下一个桃子。聪明的你,请帮悟空算一下,他第一天开始吃的时候桃子一共有多少个呢?。
请通过递归形式实现。

函数接口定义:

int Peach(int day);

该函数返回第day天所剩的桃子。用递归实现。

裁判测试程序样例:

#include <stdio.h>
 int n;
 int Peach(int day);
 int main ()
 {
 scanf("%d", &n);
 printf("%d\n", Peach(1));//不同在这里,固定输入值为1
 return 0;
 }
 /* 请在这里填写答案 */

输入样例:

3

输出样例:

10
 源代码
int Peach(int day)
{
	if(day==n)//相当于第一天只有一个桃子
	{
		return 1;	
	}
	else
	{
		return Peach(day+1)*2+2;//这里跟之前的不一样,这里是相当于将day往后推,直到第n天	
	}	
}

 指针

1.数组指针作函数参数

这个题目难度不难,但是需要运用到数组指针这个知识点,所以拿出来看看,毕竟个人觉得这是一个容易忘的知识点

题目描述


输入m个学生(最多30人)n门课程(最多5门)的成绩,然后计算并打印每个学生各门课的总分和平均分。其中,m和n的值由用户从键盘输入。

输入格式:

输入顺序如下:

学生个数m 课程数n
学生1课程1分数 学生1课程2分数 ... 学生1课程n分数
学生2课程1分数 学生2课程2分数 ... 学生2课程n分数
...
学生m课程1分数 学生m课程2分数 ... 学生m课程n分数
输出格式:

每个学生总分(整数) 平均分(实数,保留1位小数

输入样例:

在这里给出一组输入。例如:

2 3
61 62 70
75 82 90
输出样例:

在这里给出相应的输出。例如:

193 64.3
247 82.3
 源代码
#include<stdio.h>
int n,m;
void printf_number(int (*arr)[]);
int main()
{
    scanf("%d %d",&m,&n);
    int i,j;
    int arr[m][n];
    for(i=0;i<m;i++)
    {
        for(j=0;j<n;j++)
        {
            scanf("%d",&arr[i][j]);
        }
    }
  printf_number(arr);
}
void printf_number(int (*arr)[n])//传数组指针
{
    int i,j;
     double sum;
    for(i=0;i<m;i++)
    {
        sum=0;
        for(j=0;j<n;j++)
        {
            sum+=*(*(arr+i)+j);//这里值得注意一下这种写法
        }
        printf("%.0lf ",sum);
        sum=sum/n*1.0;
        printf("%.1lf",sum);
        printf("\n");
    }
}

 2.报数

题目描述

输入两个正整数 n 和 m( (1<m<n<=50)),有 n 个人围成一圈,按顺序从 1 到 n 编号。从第一个人开始报数,报数 m 的人退出圈子,下一个人从 1 开始重新报数,报数 m 的人退出圈子。如此循环,直到留下最后一个人。请按退出顺序输出退出圈子的人的编号,以及最后一个人的编号。

提示:将每个人的编号存入数组,从第一个人开始报数,输出报数 m 的人的编号,并将该编号清除为0,重复这样的操作直至只剩下一个不为0的数,该数就是最后一个人的编号。

输入输出示例:括号内为说明,无需输入输出

输入样例:
5               (n个人报数,n=5)
3               (报数m=3)
输出样例:
No1: 3          (第1个退出圈子的人编号是3)
No2: 1	        (第2个退出圈子的人编号是1)
No3: 5	        (第3个退出圈子的人编号是5)
No4: 2	        (第4个退出圈子的人编号是2)
Last No is: 4   (最后一个人的编号是4)
 题目难点

 1.如何做到每次报数报到m就有人退出

2.用数组储存,如何把它当成一个圈一样,不断的报数

3.如何知道哪个人退出了

4.如何按格式输出

 解决方案

1.这里我运用了time这个变量来储存报到的次数,到m就更新为0

2.这里我运用了指针,每次一到末尾就将它重新指向开头

3.将退出的人定义为0,最后用循环就可以很清楚的知道剩下的是谁

4.将最后一个退出的人单独处理

 源代码
#include<stdio.h>
int main()
{
   int n,m;
   scanf("%d",&n);
   scanf("%d",&m);
   int arr[n];
   int i;
   for(i=0;i<n;i++)
   {
   	arr[i]=i+1;//加1,方便操作
   }
   int out=0;int time=0;int *p=arr;
   while(out<n-1)
   {
   	if(*p!=0)time++;
   	if(time==m)//若报到m
   	{
   		printf("No%d: %d\n",out,*p);
		time=0;//次数归零
		out++;//统计出去的人的个数
		*p=0;	//将这个数标记为0,这样就知道哪些人出去了
	}
	p++;//指针不断移动
	if(p==arr+n)//若到了末尾,重新更新到开头,这样就相当于模拟了一个圈
	{
		p=arr;
	}
   }
   for(i=0;i<n;i++)
   {
//最后一个特别处理,只需要找到数没有被归零的就可以了
   	if(arr[i]!=0)
   	{
   		printf("Last No is: %d",arr[i]);
	}
   }
}

结尾:

还是那句话:记得坚持做题

  • 16
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值