翻煎饼 swustoj 254

题目描述:

麦兜最喜欢的食物是煎饼,每次在街上看到煎饼摊的时候都会在那里停留几分钟。最吸引麦兜还是煎饼师傅那一手熟练的翻煎饼的技术,一堆煎饼在那里,师傅只需要用铲子翻几下,就让煎饼整齐的叠在了一起。 这天,为了庆祝麦兜被保送上研究生,他从煎饼师傅那里买回来一些煎饼请客。但是麦兜买回的煎饼大小不一,麦兜太想吃煎饼了,他想吃这些煎饼中最大的那个。麦兜还知道同学们也很喜欢煎饼,为了表示他的诚意,他想让同学们先吃,麦兜最后吃,因此,麦兜想把煎饼按照从小到大的顺序叠放在一起,大的在最下面。这样麦兜就可以在最后拿到最大的那一块煎饼了。 现在请你帮助麦兜用煎饼师傅翻煎饼的方法把麦兜买的煎饼从小到大的叠在一起。煎饼师傅的方法是用铲子插入两块煎饼之间,然后将铲子上的煎饼翻一转,这样铲子上第一个煎饼就被翻到了顶上,而原来顶上的煎饼则被翻到了刚才插入铲子的地方。麦兜希望这样翻煎饼的次数最少。



Description
输入包括两行,第一行是一个整数n(1<=n<=1000),表示煎饼的个数,接下来的一行有n个不相同的整数,整数间用空格隔开,每个整数表示煎饼的大小(直径),左边表示顶部,右边表示底部。


Input
输出为一行,翻煎饼的最少次数


Output
1
2
3
5
5 4 2 3 1
Sample Input
1

4



解题思路:

简单来说,使用贪心策略,如果 想要煎饼从小到大排列,那么我们需要将当前最大 的煎饼归位(应该在的位置),然后将次大的煎饼归位,依次反复 下去,那么我们得到的一定是一个从小到大排列的一堆煎饼。

详解:

我们 用一个数组赋复制存储原来的数据,并将此数组 数据从小到大排序,这样我们就 可以知道每个数据 最终有序时候该在的位置,

那么

1. 我们从原始的数组中找到最大的数据的下标,如果没有恰好在归位后的位置上时:如果 数据的位置是在最上边,那么我们只需要将其翻转到最下面即可,如果不在最上面,那么我们先从此 下标将数据翻转到 最顶上,然后再翻转到最下面。即完成了 最大数据的归位。

2.次大的数据的操作与1操作一样,

.....

最终所有的数据 都会归位。


code:

#include<stdio.h>
#include<algorithm>
using namespace std;
int ans = 0;
void Change(int a[], int low, int high)  //翻转煎饼操作
{
	int i, j;
	for (i = low, j = high; i < j; i++, j--)
	{
		int temp = a[i];
		a[i] = a[j];
		a[j] = temp;
	}
}
int main()
{
	ans = 0;
	int n;
	int i, j;
	int a[1005], b[1005];
	scanf("%d", &n);
	for (i = 1; i <= n; i++)
	{
		scanf("%d", &a[i]);
		b[i] = a[i];
	}
	int e = n;
	sort(b+1, b + 1 + n);   //为了知道最终每个数据的位置,我们需要一个数组b,并排序,得到每个数据归位后的下标值 
	for (i = n; i >= 0; i--)
	{
		for (j = 1; j <= e; j++)
		{
			if (a[j] == b[i] && j != e)    //通过比较得到未归位数据中最大的数据的下标,并且没有恰好在最终归位的位置上 
			{
				if (j != 1)         //没有 在顶层
				{
					ans++;
					Change(a, 1, j);   //从当前位置翻转到顶层
				}
				
				Change(a, 1, e);  //然后再翻转一次进行此时数据的归位
				ans++;
				break;
			}
		}
		e--;
	}
	printf("%d\n", ans);
	return  0;
}



要注意的是,数组 存储时,最好从1开始,而尽量不要  从0开始,因为如果你头脑不清楚的话,很容易造成错误的翻转,出现一些bug。

对于翻煎饼还有更优的算法,,改天再说,太晚 了,睡觉咯。

你可能感兴趣的:(ACM)