例题8-1 UVA120 Stacks of Flapjacks(24行AC代码)

紫书刷题进行中,题解系列【GitHub|CSDN

例题8-1 UVA120 Stacks of Flapjacks(24行AC代码)

题目大意

给定一叠具有半径大小的煎饼,从下到上位置编号为1n,有翻转操作flip(i),表示将第in个位置的元素翻转。

现问如何用最少次数将所有煎饼从上到下按半径升序排列?

思路分析

有点像汉诺塔,不过这个是分治法的例题,通过研究样例,可以发现算法:

1. 从底到顶开始枚举位置j
2. 在[j,0]选取最大值位置pos
3. 若pos不为j,进入步骤4
4. 若pos不为顶部,则翻转[0,pos]; 翻转[0,j]

本质是现将当前最大元素翻转到顶部,再将其翻转到正确位置。翻转可用stl的reverse实现

关于最大值选取,有两种方式

  • max_element:stl算法库/手动实现
  • 将输入数组降序排列,枚举该数组时,查找相应元素即可

AC代码(C++11)

max_element

#include<bits/stdc++.h>
using namespace std;
int pc[32], n;
int main() {
    string line;
    while (getline(cin, line)) {
        cout <<line <<endl; // 输出原序列
        stringstream input(line); n = 0;
        while (input >>pc[n]) n ++; // 分割得到所有数字
        for (int i=0; i < n-1; i ++) { // 从大到小依次归位煎饼
            int pos = max_element(pc, pc+n-i) - pc; // 找到最大值的下标
            if (pos != n-i-1) { // 未正常归位
                if (pos != 0) { // 不在栈顶
                    printf("%d ", n - pos); // 输出位置
                    reverse(pc, pc+pos+1); // 翻转到最上层
                }
                printf("%d ", i+1); // 第二次输出
                reverse(pc, pc+n-i); // 翻转到正确位置
            }
        } 
        puts("0");
    }
    return 0;
}

sort+find

#include<bits/stdc++.h>
using namespace std;
int pc[32], tpc[32], n;
int main() {
    string line;
    while (getline(cin, line)) {
        stringstream input(line); n = 0;
        while (input >>pc[n]) n ++; // 分割得到所有数字
        for (int i=0; i < n; i ++) printf("%d ", pc[i]); puts(""); // 输出原序列
        memcpy(tpc, pc, sizeof(pc)); // 拷贝pc数组 
        sort(tpc, tpc+n, [](int a, int b) {return a > b;}); // 降序排列,处理最大值问题
        for (int i=0; i < n-1; i ++) { // 从大到小依次归位煎饼
            int pos = find(pc, pc+n-i, tpc[i]) - pc; // 找到tpc[i]在pc中的下标
            if (pos != n-i-1) { // 未正常归位
                if (pos != 0) { // 不在栈顶
                    printf("%d ", n - pos); // 输出位置
                    reverse(pc, pc+pos+1); // 翻转到最上层
                }
                printf("%d ", i+1); // 第二次输出
                reverse(pc, pc+n-i); // 翻转到正确位置
            }
        } 
        puts("0");
    }
    return 0;
}
发布了128 篇原创文章 · 获赞 87 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_40738840/article/details/104546472