uva 120 Stacks of Flapjacks

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=100977#problem/A

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=(1<<29);

int a[maxn],n;
char s[maxn];int ls;
int tmp[maxn];

void flip(int x)
{
    REP(i,1,x) tmp[i]=a[x+1-i];
    REP(i,1,x) a[i]=tmp[i];
    printf("%d ",n+1-x);
}

void solve(int *a,int m)
{
    if(m==1) return;
    int x=1;
    REP(i,1,m) if(a[i]>a[x]) x=i;
    if(x!=m){
        if(x!=1) flip(x);
        flip(m);
    }
    solve(a,m-1);
}

int main()
{
    freopen("in.txt","r",stdin);
    while(gets(s)!=NULL){
        ls=strlen(s);
        if(ls==0) continue;
        s[ls]=' ';s[++ls]='\0';
        n=0;
        int t=0;
        REP(i,0,ls-1){
            if(s[i]==' '){
                a[++n]=t;
                t=0;
            }
            else t=t*10+s[i]-'0';
        }
        s[ls-1]='\0';
        printf("%s\n",s);
        solve(a,n);
        puts("0");
    }
    return 0;
}

/**
题意:
    给一个序列,每次操作flip(i),即反转1~i这个区间,求使之升序的最少操作并输出操作。
分析:
    每次使最大数回到原位,最多两步,显然最优。先解1~n,先把最大数flip到1,再flip到n,然后解1~n-1,
    如此递归下去。
类型:
    贪心
注意事项:
    似乎没有。
坑点:
    1,一开始题目读错了。。。fuck。。。
    2,uva的输入还是这么感人。。
总结:
    这种交换位置排序的贪心类型,可以先使某个特殊的数(可能是最值或中点或端点值等)回原位,
    然后递归解决。
*/
View Code

 

posted @ 2015-11-30 12:17  __560  阅读(165)  评论(0编辑  收藏  举报