题目:
麦兜最喜欢的食物是煎饼,每次在街上看到煎饼摊的时候都会在那里停留几分钟。最吸引麦兜还是煎饼师傅那一手熟练的翻煎饼的技术,一堆煎饼在那里,师傅只需要用铲子翻几下,就让煎饼整齐的叠在了一起。 这天,为了庆祝麦兜被保送上研究生,他从煎饼师傅那里买回来一些煎饼请客。但是麦兜买回的煎饼大小不一,麦兜太想吃煎饼了,他想吃这些煎饼中最大的那个。麦兜还知道同学们也很喜欢煎饼,为了表示他的诚意,他想让同学们先吃,麦兜最后吃,因此,麦兜想把煎饼按照从小到大的顺序叠放在一起,大的在最下面。这样麦兜就可以在最后拿到最大的那一块煎饼了。 现在请你帮助麦兜用煎饼师傅翻煎饼的方法把麦兜买的煎饼从小到大的叠在一起。煎饼师傅的方法是用铲子插入两块煎饼之间,然后将铲子上的煎饼翻一转,这样铲子上第一个煎饼就被翻到了顶上,而原来顶上的煎饼则被翻到了刚才插入铲子的地方。麦兜希望这样翻煎饼的次数最少。
输入:
输入包括两行,第一行是一个整数n(1<=n<=1000),表示煎饼的个数,接下来的一行有n个不相同的整数,整数间用空格隔开,每个整数表示煎饼的大小(直径),左边表示顶部,右边表示底部。
输出:
输出为一行,翻煎饼的最少次数
样例:
输入
5
5 4 2 3 1
输出
4
思路:因为得到的翻煎饼的最终答案是有序的,所以我们可以先对其进行排序,得到它应该有的顺序,然后看煎饼原来的下标和排过序的下标是不是一样的。注意,因为我们是从下到上还原煎饼的位置的,所以我们每次还原一次煎饼的位置,就不用管最后一个煎饼了,即n–。
C++代码
#include<iostream>
#include<algorithm>
using namespace std;
int n;//煎饼个数
int sum;//反转次数
int a[1001];//原来煎饼的序列
int b[1001];//排过序的煎饼序列
void change(int high,int low){//对煎饼进行翻转
for(int i=high,j=low;i<j;++i,--j){
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
int main(){
cin>>n;
int e=n;//为了防止修改n 用e来接收n
for(int i=0;i<n;++i){
cin>>a[i];
b[i]=a[i];
}
sort(b,b+n);//排序
for(int i=n-1;i>=0;--i){//从b数组的最后开始判断
for(int j=0;j<e;++j){
if(a[j]==b[i]&&j!=e-1){//a数组和b数组对应的值相等
//那么就应该把a数组的值翻到b数组相同的位置上
//如果当前a数组的值在最底下 就可以不用管
//只有在中间和最上面的时候才会进行翻转操作
if(j!=0){//如果煎饼不在最上面
//那就需要把它翻到最上面 再翻到对应位置
//一定要注意下标是从哪里开始的
//我因为这个WA了好多次QAQ菜鸡落泪
sum++;//次数++
change(0,j);//把煎饼翻到第一个位置处
}
sum++;//次数++
change(0,e-1);//翻到最下面
break;//翻到最下面就可以退出了
}
}
e--;//当翻完一次的时候 最后一个煎饼就可以不用管了
}
cout<<sum<<endl;
return 0;
}