UVa 120|Stacks of Flapjacks|暴力

31 篇文章 0 订阅

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

题目

栈和队列通常被认为和数据结构的面包、黄油一样,在建筑、解析、操作系统和离散事件模拟等领域有应用。栈也对一些严谨的语言很重要。本问题涉及黄油和食物(这里用薄饼代替面包,因为翻动薄饼有一个独特而又完整系统的规则)。
给定一堆摞在一起的薄饼,你需要写个程序计算这摞薄饼怎么排序才能使得最大的薄饼在最底下,最小的薄饼在最上方。薄饼的大小用其直径定义。所有薄饼的直径互不相同。我们用翻转薄饼这个操作来排序这个栈。flip(i)操作表示翻转最上面到从下往上数的第i个薄饼,即倒置位置。最底下的薄饼为第1个,最上面的薄饼为第n个。
我们这里用一个薄饼的直径组成的栈描述问题。必须考虑只有3个元素的栈(其中最左边那个栈的最上面的8表示栈顶):

8     7     2
4     6     5
6     4     8
7     8     4
5     5     6
2     2     7

第一个栈执行操作flip(3)后变成第2个栈,再执行flip(1)后变成第3个栈。

输入

输入包含多组数据,每组数据一行 n(1n30) 个整数 di(1di100) (当然n要你自己算)。 di 表示从上往下数的第i个的直径为多少。

输出

对于每组数据,先输出原栈是怎么样的,然后再输出一行表示flip操作数的数列,并以0结尾表示数列结束(此时栈已经排序好了)。

样例输入

1 2 3 4 5
5 4 3 2 1
5 1 2 3 4

样例输出

1 2 3 4 5
0
5 4 3 2 1
1 0
5 1 2 3 4
1 2 0

题解

由于题目没有说输出的方案的要求,也就是说我们可以随便输出一种,那么我们就可以规定输出的规则。由于我们翻一次薄饼,最底下的是不受影响的,所以如果最大的饼在从下往上数的第i位置,执行flip(i)再执行flip(1)就可以把这个饼调整到最底下,然后只要我们不执行flip(1),这个饼就不会被动。所以我们把饼从大到小依次执行flip函数归位即可。

#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <cstring>
using namespace std;
int d[1024], d2[1024];
int main() {
    int sz, n, i, j, bottom;
    string s;
    while (getline(cin, s)) {
        cout<<s<<endl;
        stringstream ss;
        ss<<s; sz = 0;
        for (n = 1; ss>>d[n]; ++n) sz = max(sz, d[n]); --n;

        bottom = n;
        memcpy(d2, d, sizeof d);
        sort(d2 + 1, d2 + n + 1);
        for (i = n; i > 1; --i) {
            for (j = i; d[j] != d2[i]; --j);
            if (i == j) continue;

            if (j != 1) {
                reverse(d + 1, d + j + 1);
                cout<<n - j + 1<<' ';
            }

            reverse(d + 1, d + i + 1);
            cout<<n - i + 1<<' ';
        }
        cout<<0<<endl;
    }

    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值