链接戳这里
有一叠煎饼,每张煎饼有它的尺寸,每次操作可以用刀从某一层把该层上面的所有煎饼翻过来。请问怎么翻能使得所有煎饼从上到下尺寸为从小到大?
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;
}
网友评论