在編程之美上看到一個翻轉烙餅的排序問題,就拿過來練練手了。
問題是這樣的,一個有強迫症的人,在一家飯店裏端盤子,這裏的烙餅很暢銷,顧客一般會點很多的烙餅,可是烙餅是手工的,大小不一,放在一個盤子裏大大小小不整齊,強迫症的人看不下去了,於是就想把烙餅按大小給拍好序,整齊的呈現給顧客。不過他只有兩隻手,一隻手端盤子了,只有一隻手可以用來給烙餅排序,一隻手只能抓起一摞烙餅,然後進行翻轉這麼簡單的操作,所以他就試着通過數次翻轉來排序。那麼,問題來了,他該如何排序來使得翻轉次數最少?
看過之後,我的想法是:
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;
}