【思維】Stacks of Flapjacks
阿新 • • 發佈:2017-09-10
def ostream wap tmp char highlight break strong return
[UVa120] Stacks of Flapjacks
算法入門經典第8章8-1 (P236)
題目大意:有一個序列,可以翻轉[1,k],構造一種方案使得序列升序排列。
試題分析:從插入排序即可找到思路。每次我們優先地將沒有到自己位置上的、最大的數挪到自己的位置上。
為什麽可以這樣做呢?難道不會改變已經排好序的麽。
不會,因為我們從大往小處理,翻轉的是前面的一段,而排好序的是後面一段,因此肯定不會打亂後面的。
對於每一個數,設其下標為pos,已經排好序的有x個,那麽我們先將pos其變為1,即翻轉[1,pos],然後將其翻轉到N-x那裏去,所以再翻轉[1,N-x]。
代碼:
#include<iostream> #include<cstring> #include<vector> #include<queue> #include<algorithm> using namespace std; #define LL long long inline int read(){ int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c==‘-‘) f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-‘0‘; return x*f; } const int INF=9999999; const int MAXN=100000; int a[MAXN+1]; int cnt; int N,M; char str[MAXN+1]; int b[MAXN+1]; bool cmp(int a,int b){ return a>b; } int ret; void ref(int k){ for(int i=1;i<=k/2;i++) swap(a[i],a[k-i+1]); return ; } int ans[MAXN+1]; int main(){ while(scanf("%d",&a[1])!=EOF){ ret=0; gets(str); cnt=1; int len=strlen(str); for(int i=0;i<len;i++){ if(str[i]==‘ ‘) continue; else { int p=i+1; int sum=str[i]-‘0‘; while(isdigit(str[p])){ sum=sum*10+str[p]-‘0‘; ++p; } i=p; a[++cnt]=sum; } } N=cnt; for(int i=1;i<=N;i++) b[i]=a[i]; for(int i=1;i<N;i++) printf("%d ",b[i]); printf("%d\n",b[N]); sort(b+1,b+N+1,cmp); for(int i=1;i<=N;i++){ int tmp; for(int j=1;j<=N;j++){ if(a[j]==b[i]) { tmp=j; break; } } if(tmp==b[i]) continue; if(tmp!=1){ ans[++ret]=N-tmp+1; ref(tmp); } if(b[i]!=1){ ans[++ret]=i; ref(N-i+1); } } for(int i=1;i<=ret;i++) printf("%d ",ans[i]); puts("0"); } return 0; }
【思維】Stacks of Flapjacks