uva 120 Stocs of Flap jacks入門経典II第8章例題8-1


テーマリンク:http://uva.onlinejudge.org/index.php?option=com_オンラインjudge&Itemid=8&category=3&page=show_problem&problem=56
テーマ分析:n個の数(n<=30)を入力して、番号0~n-1を仮定して、サブシーケンスの中で最大の数を位置0と交換します。(位置0と0は交換しなくてもいいです。)その後、このサブシーケンスを反転して、最終的な配列は小さいから大きいまで並べます。
(位置pはサブシーケンスの中で最大の位置です。交換するたびに1つの数、すなわちn-pを出力します。右から左へ数番目の数を表します。説明がよくないなら、サンプルを見てください。)
サンプル分析:入力8 4 6 7 5、
①:8が最大の数(位置0と0は交換しなくてもいい)で、位置0を最後の位置に交換します。すなわち2 5 7 6 4 8です。
②:2 5 7、4の中で7が一番大きくて、位置0を位置2と交換します。つまり7を交換した後:7 5、2、4 4を反転します。つまり4 6、5を7とします。交換し始めたばかりの8は動かなくてもいいです。このステップの交換の結果:4 6、2、5、7 8は8です。
③:4 6 2の中で6が一番大きくて、6を位置0、すなわち6 4の2 5に交換して、逆転します。すなわち5の2 4の6は前の2つのステップの結果、すなわち5の2の4の6の7の8を加えます。
④:5 2 4の中で5が一番大きい(位置0と0は交換しなくてもいい)、そして逆転します。すなわち4 2 5、前の3歩の結果を加えます。すなわち4 2、5、7 8
⑤:4 2の中で4最大(位置0と0は交換しなくても良い)で、2の4を反転させ、前の4ステップの結果、すなわち2の4 5、6、7の8を加えて、終了する。
出力について:位置kは、交換するたびに右から左に数番目の数を出力します。最後に0を出力します
①:8と2(即位0と位置5)が入れ替わると1が出力され、右から左へ2が最初の数なので1が出力されます。
②:2 5、7、4のうち2と7を入れ替えて出力する(右から左へ7は4番目の数)。そして反転して、2を出力します。
     ③:4 6 2 5 7中4と6を入れ替えて5を出力し、反転して3を出力します。
④:出力4.
⑤:出力5.
最後に0を出力して終了します。
コードは劉汝佳コードをまねて書きました。
#include<cstdio>
#include<iostream>
#include<string>
#include<sstream>
#include<algorithm>
using namespace std;

int n,a[55];

void file(int p){
    for(int i=0;2*i<p;i++)//     i<p/2
        swap(a[i],a[p-i]);
    printf("%d ",n-p);
}

int main(){
    string s;
    while(getline(cin,s)){
        cout << s << endl;
        stringstream ss(s);
        n=0;
        int num;
        while(ss >> num) a[n++]=num;

        for(int i=n-1;i>0;i--){
            int p=max_element(a,a+i+1)-a;
            if(i==p) continue;
            if(p>0) file(p);
            file(i);
        }
        printf("0
"); } return 0; }