poj 2275 Flipping Pancake

#include <iostream>        //翻烧饼问题
#include <algorithm>
#include
<vector>
using namespace std;
int list[35];
vector
<int> col;
void flip(int p)
{
reverse(list,list
+p); //reverse(&list[0],&list[p]);
col.push_back(p);
}
int main()
{
int pos,i,j,len;
while(scanf("%d",&len)&&len)
{
col.clear();
for(i=0;i<len;++i)
scanf(
"%d",&list[i]);
for(pos=len-1;pos>0;--pos) //最外一层的for每次循环都使得 list[pos]=pos+1 ,即当前最大数翻到当前的最下面(下标当前最大)
{
if(list[pos]!=pos+1) //如果目前的最大值已经位于list[pos]上,则跳过
{
for(i=pos-1;i>=0;--i)
{
if(list[i]==pos+1) //找出目前的最大值
break;
}
int flag=0; //找出最大值的次小值,比它小1
for(j=i-1;j>=0;--j)
{
if(list[j]==pos)
{
flag
=1;break;
}
}
if(flag) //如果次小数在当前的最大数的左边,则要使次小数紧挨着当前的最大数
{
if(j!=0)
flip(j
+1); //先把次小数调到最上面
flip(i); //使次小数紧挨着当前的最大数,在当前的最大数的左边,
//这样做,接下来翻转当前的最大数到最下面时就能顺便使次小数也紧跟在最大数的左边,总的来说可以减少翻转次数
}

if(i!=0) //使当前的最大数翻到最下面:list[pos]=pos+1
flip(i+1);
flip(pos
+1);
}
}
cout
<<col.size()<<" ";
for(int i=0;i<col.size();++i)
cout
<<col[i]<<" ";
cout
<<endl;
}
return 0;
}

//Sample的第二组测试数据 5 4 3 2 5 1 结果为 3 3 4 5 (表示前i个元素反转)
// 数列 4 3 2 5 1 经 3 4 5 过程:(1)3 : 2 3 4 5 1 (2)4: 5 4 3 2 1 (3)5: 1 2 3 4 5

  

posted on 2011-07-22 16:33  sysu_mjc  阅读(347)  评论(0编辑  收藏  举报

导航