SWUST OJ 254:翻煎餅問題
問題描述:
麥兜最喜歡的食物是煎餅,每次在街上看到煎餅攤的時候都會在那里停留幾分鍾。最吸引麥兜還是煎餅師傅那一手熟練的翻煎餅的技術,一堆煎餅在那里,師傅只需要用鏟子翻幾下,就讓煎餅整齊的疊在了一起。 這天,為了慶祝麥兜被保送上研究生,他從煎餅師傅那里買回來一些煎餅請客。但是麥兜買回的煎餅大小不一,麥兜太想吃煎餅了,他想吃這些煎餅中最大的那個。麥兜還知道同學們也很喜歡煎餅,為了表示他的誠意,他想讓同學們先吃,麥兜最后吃,因此,麥兜想把煎餅按照從小到大的順序疊放在一起,大的在最下面。這樣麥兜就可以在最后拿到最大的那一塊煎餅了。 現在請你幫助麥兜用煎餅師傅翻煎餅的方法把麥兜買的煎餅從小到大的疊在一起。煎餅師傅的方法是用鏟子插入兩塊煎餅之間,然后將鏟子上的煎餅翻一轉,這樣鏟子上第一個煎餅就被翻到了頂上,而原來頂上的煎餅則被翻到了剛才插入鏟子的地方。麥兜希望這樣翻煎餅的次數最少。
輸入:輸入包括兩行,第一行是一個整數n(1<=n<=1000),表示煎餅的個數,接下來的一行有n個不相同的整數,整數間用空格隔開,每個整數表示煎餅的大小(直徑),左邊表示頂部,右邊表示底部。
輸出:輸出為一行,翻煎餅的最少次數(注意要換行 \n)
樣例:
思路:首先要摸清楚怎么去翻煎餅,其實就是將這n個煎餅的個數,簡化成兩個煎餅或整體(插入說位置可以是煎餅,也可以是縫隙),分為兩個步驟:
1.將相對最大的煎餅翻在最上面
2.再將它翻下來
忽略已確定的位置,重復以上步驟,可以用迭代也可以用遞歸
翻煎餅的過程有點像鏡像
如:(下划線表示位置已確定)
5 4 2 3 1 //將4 2 3 1看作一個煎餅,5看作一個煎餅,翻,得到如下結果
1 3 2 4 5 //4,5位置已確定,只需翻 1,3,2,將1,3開翻
3 1 2 4 5 //將1,3看做一個煎餅,將2看做一個煎餅,開翻
1 2 3 4 5
代碼思路:分三種情況
1.相對最大的煎餅在最上面
2.相對最大的煎餅在中間
3.相對最大的煎餅在最下面(已確定)
代碼實現(使用C語言)
#include "stdio.h" int num=0; int turn_num =0; int max_button(int a[]) { int i=0; int max=0; int op=0; for(i=0;i<num;i++) { if(max<=a[i]) { max = a[i]; op = i; } } if(op==num-1) { return 1; } else { return 0; } } int max_op(int a[]) { int i=0; int max=0; int op=0; while(a[i]!=0) { if(max<a[i]) { max = a[i]; op = i; } i++; } return op; } void reverse(int a[],int n) { int b[1000]={0}; int i; for(i=0;i<n;i++) { b[n-i-1] = a[i]; } for(i=0;i<n;i++) { a[i] = b[i]; } } void del(int a[]) { int i; int temp = num; for(i=0;i<temp;i++) { if((max_button(a))==1) { a[num-1] = 0; num--; } } } int trun(int a[]) { int op; while(a[0]!=0) { del(a); if(max_op(a)==0) { reverse(a,num); turn_num++; } else{ op = max_op(a); reverse(a,op+1); turn_num++; } } return turn_num; } int main() { int a[3000]={0}; int i; int answer; scanf("%d",&num); for(i=0;i<num;i++) { scanf("%d",&a[i]); } answer = trun(a); printf("%d\n",answer-1); }