版权声明:本文为博主原创文章,转载请注明原博客地址 https://blog.csdn.net/qunqunstyle99/article/details/88745306
交换瓶子
有N个瓶子,编号 1 ~ N,放在架子上。
比如有5个瓶子:
2 1 3 5 4
要求每次拿起2个瓶子,交换它们的位置。
经过若干次后,使得瓶子的序号为:
1 2 3 4 5
对于这么简单的情况,显然,至少需要交换2次就可以复位。
如果瓶子更多呢?你可以通过编程来解决。
输入格式为两行:
第一行: 一个正整数N(N<10000), 表示瓶子的数目
第二行:N个正整数,用空格分开,表示瓶子目前的排列情况。
输出数据为一行一个正整数,表示至少交换多少次,才能完成排序。
例1
输入:
5
3 1 2 5 4
输出:
3
例2
输入:
5
5 4 3 2 1
输出:
2
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
题目分析及代码实现
一开始我想的比较复杂,感觉这个题目有点麻烦,后来仔细想了想,拿了几个例子试了一下,发现 只要每次交换都可以确定一个瓶子的位置,那就是最少的交换次数,与确定位置无关
因此,为了方便遍历,我们可以从小到大开始确定顺序,也可以从大到小,(交换方法可参考交换排序法)
import java.util.Scanner;
public class changeBottle {
static int count = 0;//计数
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
int start = 0; //记录未排好序的瓶子起始位置
int N = scanner.nextInt();
int numofBottle[] = new int[N];
for(int i = 0;i<N;i++)
numofBottle[i] = scanner.nextInt();
scanner.close();
int time = 0;
while(start != numofBottle.length) {
if(numofBottle[time]==time+1) {//若瓶子就在正确位置
start++;
time++;
continue;
}else {
//需要交换
change(numofBottle,start, findMin(numofBottle, start));
time++;
start++;
}
}
System.out.println(count);
}
//知道未排序瓶子中最小的序号,可以全部遍历找最小的,也可以查找值等于待排序start+1的下标,这个会更节省时间一些
//也可以用map存贮,查找会更方便,但是交换顺序不如数组方便
public static int findMin(int a[],int start) {
int min = 10000;
int position = 10000;
for(int i = start;i<a.length;i++) {
if(a[i]<min) {
min = a[i];
position = i;
}
}
return position;//返回下标
}
//交换位置
public static void change(int a[],int key,int value) {
int temp;
temp = a[value];
a[value] = a[key ];
a[key ] = temp;
count++;//每交换一次,次数加一
}
}