从网上搜到蓝桥杯竞赛题目,发给同学们练着做,收到宋佳同学和溢卓同学的两段代码,而且是两个思路,都非常好,加油!
一、题目描述
交换瓶子:有N个瓶子,编号 1 ~ N,放在架子上。
比如有5个瓶子:
2 1 3 5 4
要求每次拿起2个瓶子,交换它们的位置。
经过若干次后,使得瓶子的序号为:
1 2 3 4 5
对于这么简单的情况,显然,至少需要交换2次就可以复位。
如果瓶子更多呢?你可以通过编程来解决。
输入格式为两行:
第一行: 一个正整数N(N<10000), 表示瓶子的数目
第二行:N个正整数,用空格分开,表示瓶子目前的排列情况。
输出数据为一行一个正整数,表示至少交换多少次,才能完成排序。
例如,输入:
5
3 1 2 5 4
程序应该输出:
3
再例如,输入:
5
5 4 3 2 1
程序应该输出:
2
二、宋佳同学交换
- 解题思路
以第一组数据为例:3 1 2 5 4
步骤:
(1)从第1个数开始;
(2)检查当前数是不是在它应该在的位置,例如第1个数3,3不是它该在的位置,那么就把它放在该放的位置,因此第一次交换是3和2进行交换,即3和第3个数进行交换;
(3)交换完后,还要检查交换后的当前数,如果交换完后,当前数已经是正确位置,再检查下一个数,然后转向步骤1;
(4)重复2-3步骤,直到把所有数检查完毕。
交换过程如图1所示:
程序代码
#include<iostream>
using namespace std;
int main() {
int n; //数据的个数
int t; //中间变量
int sum=0;
char ch='a';
cout<<sizeof(int)<<endl;
cin >> n;
int *a= new int[n + 1];
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
sum = 0;
for (int i = 1; i <= n; i++) {
if (a[i] != i) { //如果没有在该在的位置
t = a[i]; //t为当前数该在的为
a[i] = a[t]; //把该在位置的数交换成当前的数
a[t] = t; //将当前数放在它该在的位置
sum++; //交换次数加1
i--; //为的是接下来还是检查当前数
}
}
cout << sum << endl;
wcout<<sum<<endl;
}
三、溢卓同学交换
- 解题思路
还是以第一组数据为例:3 1 2 5 4
步骤:
(1)从第1个数开始;
(2)检查此数是不是正确位置,如果不是,那么后面的数中谁该是这个位置的数,就和谁进行交换;
(3)接下来检查下一个数,转向步骤2;
(4)重复步骤2-3,直到所有数据被检查完毕。交换过程如图2所示:
- 程序代码
#include <malloc.h>
#include <stdio.h>
int main(){
int n; //数据的个数
int i,j,t,min,count=0; //交换次数
printf("请输入个数\n");
scanf("%d",&n);
int *a=(int *)malloc((n+1)*sizeof(int)); //申请空间
//输入数据
for(i = 1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=n;i++){
if(a[i]!=i) //如果是当前数是正确位置则检查下一个数,当前数据不是正确位置
{
for( j = i+1; j<=n;j++){ //找最小
if(a[j]==i)
{
min = j; //找到j位置的数组元素是i
break; //中断循环
}
}
//下面开始交换 当前数a[i]和a[min]进行交换
t=a[i];
a[i] = a[min];
a[min] = t;
count++; //有交换时计数器加1
}
}
printf("%d",count);
return 0;
}
溢卓同学是用C语言写的,结果也正确,但比较起来代码比宋佳同学的代码繁琐一些,用了两次循环。
四、题目拓展
n个数据元素是输入的,请大家写代码,完成将1-n个数据随机存入数组元素a[1]-a[n]中。
请同学们完成代码。