在编程之美上看到一个翻转烙饼的排序问题,就拿过来练练手了。
问题是这样的,一个有强迫症的人,在一家饭店里端盘子,这里的烙饼很畅销,顾客一般会点很多的烙饼,可是烙饼是手工的,大小不一,放在一个盘子里大大小小不整齐,强迫症的人看不下去了,于是就想把烙饼按大小给拍好序,整齐的呈现给顾客。不过他只有两只手,一只手端盘子了,只有一只手可以用来给烙饼排序,一只手只能抓起一摞烙饼,然后进行翻转这么简单的操作,所以他就试着通过数次翻转来排序。那么,问题来了,他该如何排序来使得翻转次数最少?
看过之后,我的想法是:
1.先看最大的是否在最下面。
1.1如果在,则无需操作.
1.2如果不是,则看是否在最上面,如果在最上面,则进行翻转,将其翻转到最下面
1.3若既不在最上面也不在最下面,则其在中间的某处,这样就先从这个最大处进行翻转,翻转后最大的饼就在最上面,在进行翻转,这样就翻转到最下面了。
2.将下面已排好序的部分固定不动,考虑剩下的烙饼中最大一张,重复1步骤。
下面是C++程序实现:
#include<windows.h>
#include<stdlib.h>
#include<iostream>
#include<vector>
using namespace::std;
int main()
{
vector<int> CakeSize;
int totalNum , contNum = 0 , MaxCake ,MaxCakeNum;
cout << "Input total number of the cake: " << endl;
cin >> totalNum;
int i = 0 , j = 0;
for (i = 0; i < totalNum; i++)
{
CakeSize.push_back(0);
}
cout << "Input each size of the cake: " << endl;
for (i = 0; i < totalNum; i++)
cin >> CakeSize[i];
for (i = 0; i < totalNum-1; i++) //当只剩一个烙饼时就无需翻转了
{
MaxCake = CakeSize[0];
MaxCakeNum = 0;
for (j = 0; j < totalNum - i; j++)
{
if (CakeSize[j] > MaxCake)
{
MaxCake = CakeSize[j];
MaxCakeNum = j;
}
}
if (MaxCakeNum == 0)
{
contNum++;
int k = 0;
vector<int> v1;
for (k = 0; k < totalNum - i; k++)
{
v1.push_back(CakeSize[totalNum - i - k-1]);//最后一个饼是totalNumb-1
} //翻转vector的乱序部分
for (k = 0; k < totalNum - i; k++)
{
CakeSize[k] = v1[k];
} //翻转vector的乱序部分
}
else if (MaxCakeNum != totalNum - i-1)
{
contNum += 2;
int k = 0;
vector<int> v1;
for (k = 0; k <= MaxCakeNum; k++)
{
v1.push_back(CakeSize[MaxCakeNum-k]);
} //翻转vector的乱序部分
for (k = 0; k <= MaxCakeNum; k++)
{
CakeSize[k] = v1[k];
}
vector<int> v2;
for (k = 0; k < totalNum - i; k++)
{
v2.push_back(CakeSize[totalNum - i - k -1]);
}
for (k = 0; k < totalNum - i; k++)
{
CakeSize[k] = v2[k];
} //翻转vector的乱序部分
}
}
cout << contNum << endl;
getchar();
getchar();
return 0;
}