uva 120 stacks of flapjacks 贪心

2018-04-02  本文已影响0人  无令便逐风

链接戳这里
有一叠煎饼,每张煎饼有它的尺寸,每次操作可以用刀从某一层把该层上面的所有煎饼翻过来。请问怎么翻能使得所有煎饼从上到下尺寸为从小到大?

8            7            2
4            6            5
6            4            8
7  ->翻第3层  8 ->翻第1层   4
5            5            6
2            2            7

思路:因为每次在a层以上的翻转都不会影响a层下面的煎饼,于是可以每次都想办法让尺寸大的煎饼到下面它该去的位置。所以方法是:选择还没有到正确位置的尺寸最大的煎饼,将它翻到最上层(如果它不在最上层的话),再把它翻到它应该去的层。

#include <iostream>
#include <bits/stdc++.h>
using namespace std;

#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define rrep(i,a,b) for(int i=(a-1);i>=(b);--i)
#define lb lower_bound
const int inf = 0x3f3f3f3f, maxN = 505;
int N, M, cnt;
// 元素和备份的参考数组
int e[35], bk[35];

// 翻转第i层
void f(int x) {
    x = cnt - (x - 1);
    // 现在有x个元素
    rep(i, 0, x / 2)
        swap(e[i], e[x - 1 - i]);
}

int main() {
    // freopen("data.in", "r", stdin);
    cnt = 0;
    while (~scanf("%d", &e[cnt++])) {
        while (getchar() != '\n')
            scanf("%d", &e[cnt++]);
        rep(i, 0, cnt)
            printf("%d ", e[i]);
        puts("");

        memcpy(bk, e, sizeof(e));
        sort(bk, bk + cnt);
        rrep(i, cnt, 0) {
            if (bk[i] != e[i]) {
                int idx;
                for (idx = 0; idx < cnt; ++idx)
                    if(e[idx] == bk[i])
                        break;
                if (idx != 0) {
                    f(cnt - idx);
                    printf("%d ", cnt - idx);
                }
                f(cnt - i);
                printf("%d ", cnt - i);
            }
        }
        puts("0");
        cnt = 0;
    }
    return 0;
}
上一篇 下一篇

猜你喜欢

热点阅读