紫书第八章例题笔记
作者:互联网
煎饼(Stacks of Flapjacks, UVa120)
有一叠煎饼正在锅里。煎饼共有\(n(n≤30)\)张,每张都有一个数字,代表它的直径大小,如图8-11所示。flip(k)
操作可以把铲子插到倒数第k张煎饼下面,并且翻转铲子上面所有的煎饼。例如,图8-11(a),依次执行操作flip(3),flip(1)
后得到图8-11(c)的情况。
设计一种方法使得所有煎饼按照从小到大排序(最上面的煎饼最小)。输入时,各个煎饼按照从上到下的顺序给出。例如,上面的例子输入为8, 4, 6, 7, 5, 2
。
输入输出
输入包含多行,每行是一组以空格分开的数字,这些是煎饼的直径。直径不会超过100,每组数不会超过30。输入代表初始时这些煎饼的序列。
对于每组输入,输出原序列和flip操作的参数,每组输出以0结束。
Sample Input
1 2 3 4 5
5 4 3 2 1
5 1 2 3 4
Sample Output
1 2 3 4 5
0
5 4 3 2 1
1 0
5 1 2 3 4
1 2 0
思路
看到题目都傻了,没啥规律可循,题目中没说明要求输出的内容中flip次数最少还是咋样,就给你几个输入输出让你做。
紫书中的思路是,假设有n个煎饼,每次在[1~n]
范围找直径最大的煎饼,如果它在位置k,先用flip(k)把它放到顶上,再用flip(1)让它到底部。这时这个直径最大的煎饼已经归到正确的位置了,我们缩小范围至[1~n-1]
,重复上面步骤。
这样确实能得到正确结果,思路也很巧妙,但是我还是不知道也不给一个输出的详细要求就让我做怎么做啊,会不会存在其他flip参数序列也能将煎饼排序???
代码
刚开始没想太多直接开始编码了,导致写的乱七八糟,心里在想很多时间优化策略,但是就这问题的输入规模,\(O(n^3)\)的时间复杂度也无所谓吧。所以应该追求简洁易懂。
#include "iostream"
#include "cstdio"
#include "string"
#include "sstream"
#include <algorithm>
#include "cmath"
#include "cstring"
using namespace std;
string line;
int stack[31]; // stack[i] 当前栈中第i张饼的直径 从1开始
int position[101]; // position[n] 饼面直径为n的元素所在栈中的位置,因为并无相同直径的饼 从1开始
int n,maxi = 0;
void read() {
memset(position, -1, sizeof(position));
stringstream ss(line);
n = 1;
while (ss >> stack[n]) { position[stack[n]] = n;maxi = max(stack[n++],maxi); }
n--;
for (int i = 1; i <= n; i++)
printf("%d%c", stack[i], i == n ? '\n': ' ');
}
void swap(int* p, int* q) {
int t = *p; *p = *q; *q = t;
}
// 从倒数第pos个开始,将i到上面的所有翻转
void flip(int pos){
if (pos == n)return;
cout << pos << " ";
for (int i = n - pos + 1, j = 1; i > j; i--, j++) {
position[stack[i]] = j; position[stack[j]] = i;
swap(stack + i, stack + j);
}
}
void solve(){
int correctCnt = 0; // 已经在正确位置的饼的数量
for (int i = maxi; i >= 0 && correctCnt <= n; i--) {
if (position[i] != -1) {
// 位置不正确,翻转
if(position[i] != n-correctCnt){
flip(n-position[i]+1); flip(correctCnt+1);
}
correctCnt++;
}
}
}
int main() {
while (getline(cin,line)) {
read();
solve();
printf("0\n");
}
return 0;
}
标签:include,紫书,int,flip,第八章,煎饼,position,例题,stack 来源: https://www.cnblogs.com/lilpig/p/14276603.html