【题目描述】
将一个数组中的值按逆序重新存放。例如,原来的顺序为8,6,5,4,1。要求改为1,4,5,6,8。
【输入】
输入为两行:第一行数组中元素的个数n(1
【输出】
输出为一行:输出逆序后数组的整数,每两个整数之间用空格分隔。
【输入样例】
5
8 6 5 4 1
【输出样例】
1 4 5 6 8
说明
主要考查一维数组的翻转算法。
本题对于初学一维数组的同学来说比较重要,详情请继续阅读下面内容。
题目概述
输入一个正整数n,表示依次输入n个整数存储在一维数组中,接着是主要的部分,有两种方案:
第一,直接反向输出n个元素。
第二,对数组的n个元素进行翻转。例如数组原来的元素是1、2、3,经过翻转处理后,变为3、2、1,最后再输出。
思路分析
在《题目概述》中讲到两种方案,其中第一种方案很简单。思路如下:
1、输入n。
2、使用循环输入n个元素给一维数组。
3、使用循环反向输出n个元素。
第二种方案思路如下:
1、输入n。
2、使用循环输入n个元素给一维数组。
3、使用循环对数组中n个元素进行翻转处理。
4、使用循环正向输出n个元素。
题目说《将一个数组中的值按逆序重新存放》,题意其实是将数组的元素翻转,应选第二种方案。
在解决问题时,不一定要按照题意解答,只要答案正确即可,这对于比赛来说特别重要。如果自己是使用了第一种方案,可以体现出自己思维较为优秀。而对于学习算法来说,必须把第二种方案学会,这是对一维数组的基本应用,初学者必须掌握对一维数组元素进行翻转的具体算法过程。
代码中将提供两种方案作为参考和对比。
重点讲解数组翻转的技巧。第一,可以声明一个临时数组辅助原数组进行翻转;第二,在原数组的基础上进行翻转。
使用临时数组的方法:
1、原数组为a,临时数组为t,它们长度应相同。
2、使用循环,要有两个控制变量i和j,变量i正向控制原数组a,变量j反向控制临时数组t(数组a不一定是正向,也可以反向,只要与数组t相反即可),依次把数组a的元素复制给数组t。例如n的值为4,将a[1]赋给t[4]、a[2]赋给t[3]、a[3]赋给t[2]、a[4]赋给t[1]。
3、使用循环,将数组t的n个元素正向赋给数组a。
上述数组a和数组t都是从下标1开始,下标0不使用。
在原数组的基础上翻转的方法:
从《使用临时数组》的方法中可以看出,是将数组n个元素的首尾元素进行交换,并从首元素开始依次递增,尾元素开始依次递减。
如上图,数组n个元素中,首元素的值为1,尾元素的值为9,将1和9交换,2和8交换,3和7交换,4和6交换,剩下只有一个5,无需交换,本来就位于中间。9个元素共交换了4次。
(上图是交换后的结果)
上面介绍了奇数数目的元素交换过程,下面介绍偶数数目的元素交换过程。其实都是一样的,只不过奇数数目的数组交换时,最后肯定剩下一个中间元素,而偶数数目的数组交换时,就不会剩下。
很明显,所有元素都有配对元素。10个元素共交换了5次。
(上图是交换后的结果)
不管n是奇数还是偶数,n个元素共交换了n/2次。如果n是奇数,例如n = 9,那么9 / 2 = 4。因为在C++中,整型数值相除时,会删掉小数点后的数字,只保留整数部分。所以,只需循环n/2次就可以完成数组的翻转。
数据类型:n的值不大于100,可选int类型。如果数组是从下标1开始使用,那么数组的长度不小于100。而经过测试,数组长度如果取100,不能通过,101就可以。所以题目(1
重难点
本题重点是学习一维数组的翻转算法。如果循环次数不是n/2,而是n,那么相当于变回原样。因为循环一半是翻转,再循环一半就变回原样了。这一点特别重要,不少同学循环了n次。
参考代码(直接反向输出)
#include
using namespace std;
int main(){
int a[101], t[101], n;
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = n; i >= 1; i--) cout <' ';
return 0;
}
参考代码(使用临时数组翻转)
#include
using namespace std;
int main(){
int a[101], t[101], n;
cin >> n;
for (int i = 1, j = n; i <= n; i++, j--)
{
cin >> a[i];
t[j] = a[i]; // 把a[i]翻过来赋给t[j]
}
for (int i = 1; i <= n; i++)
{
a[i] = t[i];
cout <' ';
}
return 0;
}
参考代码(在原数组的基础上翻转)
注意翻转算法代码中,元素a[n - i + 1]的写法。i初始为1,代表n个元素中的首元素,每循环一次,递增1。a[n]是n个元素中的尾元素,每循环一次,递减1。所以a[n - i + 1]可以写成a[n--],如此一来就会改变n的值,一般比较少这么写,不过也应根据实际情况而定。
变量i是循环增量,从首元素开始递增,而对于尾元素应是递减。所以用n-i即可实现递减。而n-i不是尾元素,不过加1后就是尾元素了,即a[n - i + 1]。
#include
using namespace std;
int main(){
int a[101], n, t; // t用于辅助数组元素交换
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
int len = n / 2; // 交换的次数
for (int i = 1; i <= len; i++)
{
t = a[i]; // 开始交换
a[i] = a[n - i + 1]; // 注意尾元素的下标
a[n - i + 1] = t;
}
for (int i = 1; i <= n; i++) cout <' ';
return 0;
}
END
注:题目来源于网络,转载于《信息学奥赛一本通(C++版)在线评测系统》,点击下方的【阅读原文】即可打开该题的链接。
题解属于本微信公众号【大神编程】原创。