1. 程式人生 > >【思維】Stacks of Flapjacks

【思維】Stacks of Flapjacks

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