Input
输入第一行:输入n值。
输入第二行:输入n个整数。
Output
输出仅二行
第一行:输出最大值和最小值
第二行:输出最大值序列号和最小值序列号。
样例输入
4
78 98 88 97
样例输出
max=98,min=78
maxi=2,mini=1
题目分析
题目要求我们写一个代码,要写出一个程序,程序核心是找出最大值,乍一看似乎需要我们把顺序排列出来,再提取出最大值与最小值,如果用冒泡排序等方法实际上小题大做。实际上并没有这个必要,我们要做的就是把最值找出来即可。
那究竟要怎么寻找最值呢?如果用简单的scanf等待输入的话,如何给这些数字一个上限n?又如何给这些数字编号?要想输入确定元素,而且能标序号,这就要使用数组了。
数组
数组需要用char定义,例如:
char ch [] ;
char ch [] = {
1,2,3,4,5};
char ch [5] = {
1,2,3,4,5};
值得注意的是,数组定义名称后面的方括号“[ ] ”可以不写具体的数值(这个数值即数组的大小),计算机会自动计算数组大小并记住这个数字;但是方括号中不能是变量。
另外,数组下标是从0开始而不是1,因此在代码块中要注意下标和序号的区别,下标 + 1 = 序号,这是在题目中需要注意的易错点。
而且数组的结束标志是"\0",而且\0不占用数组的下标号,换言之就是数组中有5个数字,大小就是5,\0不占用大小和下标。(这里有点陌生,我上面的想法可能出错)
现在问题又来到了如何输入数据。数字的数量由我们定制,n等于几,就要输入几个数字,而scanf不能保证输入的数字数量就等于n,所以需要一个循环来持续输入数字,循环中重复使用scanf接收数字。
for (int p = 0; p < n; p++)//从0开始,n-1结束scanf("%d", &ch[p]);
//数组下标从'0'开始,所以循环变量从0开始计算,在n-1结束
别忘了数组的特性!
最后是具体如何提取最值了。我们可以拿第一项为基准去比较,假设第一项最大,我们可以拿第一项慢慢向后比较,如果遇到了比它小的数字,则数字不变,下标、序号不变;如果遇到了更大的数字,那就要更替最大值,同时根据循环了i次来更换下标和序号。
以提取最大值为例:
if (ch[i] > max)//下标为i的数比最大值还要大{
max = ch[i];//最大值更换为现在的数字maxi = 1 + i;//因为是第i次循环,所以要给序号加i(实际也是给下标加i)}
这部分代码最容易在新旧两个最大值之间出现差错,最大值max在循环结束前只是暂时的值,而ch[i]有可能随时变为最大值。
总代码块:
#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>int main()
{
int n = 0;//总共多少个数字scanf("%d", &n);char ch[50];//定义一个数组for (int p = 0; p < n; p++)//数组下标从'0'开始,所以循环变量从0开始计算,在n-1结束scanf("%d", &ch[p]);//利用for循环不断输入数组中int max, min, maxi, mini;//分别定义最大值,最小值,最大值下标,最小值下标max = ch[0];//假设最大值是第一个数min = ch[0];//同样假设最小值maxi = 1;//最大值序号,注意,序号和下标不是一个东西!!!mini = 1;//最小值序号for (int i = 0; i < n; i++)//这里也要满足i < n,从0开始,到n的前一项结束{
if (ch[i] > max){
max = ch[i];maxi = 1 + i;}if (ch[i] < min){
min = ch[i];mini = 1 + i;}}printf("max=%d,min=%d\nmaxi=%d,mini=%d", max, min, maxi, mini);return 0;
}
小结
本题表面上是要排序再找最值,实际上也可以直接跳过排序部分,直捣最值处。编写时思路要清晰,什么时候给max替换新值,下标和序号要怎么加。有什么输入多个可变换数字个数的方法,这些都是核心。
若有其他方法,欢迎评论指出,我们共同探讨,共同促进!