煎饼排序 (Stacks of Flapjacks, Uva 120)

Stacks of Flapjacks的题目详见Uva 120。解法类似与插入排序,每次找未排好序列中数字最大的煎饼并将其翻至锅顶,然后将全部未排序的序列翻转。这样就排好了一个数字。

因为STL vector里面已经有max_element()和reverse(),所以直接用STL会比较方便。注意reverse里面的第二个元素是基于vector.end(),它是最后一个元素的后一个元素,所以如果第二个元素不是end()而是某个具体元素的指针的话,要加1。否则出错。

程序如下:

#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>

using namespace std;

void FlapjackSort(vector<int> &fj) {
    int n = 0;
    vector<int>::iterator iter = fj.begin();

    while(iter!=fj.end()) {
        cout<<endl<<"n=";
        vector<int>::iterator maxFj = max_element(fj.begin(), fj.end()-n);
        reverse(fj.begin(), maxFj+1);
        cout<<endl<<" ";
        for_each(fj.begin(), fj.end(), [](int i)->void {std::cout << i <<" ";});
        reverse(fj.begin(), fj.end()-n);
        cout<<" ";
        for_each(fj.begin(), fj.end(), [](int i)->void {std::cout << i <<" ";});

        n++;
        iter=fj.begin()+n;
    }

}

int main()
{
    int flapjacks[8] = {2,5,7,6,4,8,11,4};
    vector<int> fj;

    for (int i=0; i<sizeof(flapjacks)/sizeof(flapjacks[0]); i++) {
        fj.push_back(flapjacks[i]);
    }
    cout<<"original flapjacks"<<endl;
    for_each(fj.begin(), fj.end(), [](int i)->void {std::cout << i <<" ";});
    cout<<endl;

    FlapjackSort(fj);

    cout<<endl<<"after sorting"<<endl;
    for_each(fj.begin(), fj.end(), [](int i)->void {std::cout << i <<" ";});

    return 0;
}

程序输出如下:
original flapjacks
2 5 7 6 4 8 11 4

n=0
11 8 4 6 7 5 2 4 4 2 5 7 6 4 8 11
n=1
8 4 6 7 5 2 4 11 4 2 5 7 6 4 8 11
n=2
7 5 2 4 6 4 8 11 4 6 4 2 5 7 8 11
n=3
6 4 4 2 5 7 8 11 5 2 4 4 6 7 8 11
n=4
5 2 4 4 6 7 8 11 4 4 2 5 6 7 8 11
n=5
4 4 2 5 6 7 8 11 2 4 4 5 6 7 8 11
n=6
4 2 4 5 6 7 8 11 2 4 4 5 6 7 8 11
n=7
2 4 4 5 6 7 8 11 2 4 4 5 6 7 8 11
after sorting
2 4 4 5 6 7 8 11
Process returned 0 (0x0) execution time : 0.087 s
Press any key to continue.

看来用STL虽然方便,可是太慢了(可能是涉及到iterator的关系?),直接用写函数max()和reverse()可能快些。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值