UVa 120 - Stacks of Flapjacks

链接:

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=56

 

题意:

有一叠煎饼正在锅里。煎饼共有n(n≤30)张,每张都有一个数字,代表它的大小。
厨师每次可以选择一个数k,把从锅底开始数第k张及上面的煎饼整体翻转过来(即颠倒一个连续子序列)。
设计一种方法使得所有煎饼按照从小到大排序(最上面的煎饼最小)。输入时,各个煎饼按照从上到下的顺序给出。

 

分析:

构造法。按照选择排序的思想,以从大到小的顺序依次把每个数排到正确的位置。
方法是先翻到最上面,然后翻到正确的位置。
由于是按照从大到小的顺序处理,当处理第i大的煎饼时,是不会影响到第1, 2, 3,…, i-1大的煎饼的
(它们已经正确地翻到了煎饼堆底部的i-1个位置上)。

 

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <sstream>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 inline int seek(int* a, int k){
 8     for(int i = 0; ; i++){
 9         if(a[i] == k) return i;
10     }
11 }
12 
13 void solve(int* a, int n){
14     int b[100+5];
15     memcpy(b, a, sizeof(b));
16     sort(b, b + n);
17     for(int last = n - 1; last > 0; last--){
18         if(a[last] == b[last]) continue;
19         if(a[0] != b[last]){
20             int p = seek(a, b[last]);
21             printf("%d ", n - p);
22             reverse(a, a + p + 1);
23         }
24         printf("%d ", n - last);
25         reverse(a, a + last + 1);
26     }
27     printf("0\n");
28 }
29 
30 int main(){
31     char s[999];
32     while(gets(s)){
33         printf("%s\n", s);
34         int n = 0, a[100+5];
35         stringstream ss(s);
36         while(ss >> a[n]) n++;
37         solve(a, n);
38     }
39     return 0;
40 }

 

posted @ 2017-12-13 13:09  Ctfes  阅读(130)  评论(0编辑  收藏  举报