题意:有一摞大小不一的煎饼,我们只能用铲子使之翻转,可以从最下面翻转,也可以选择上面几块翻转,翻转的位置是从底层往上数,例如整摞一起翻就是0。现要求在几次翻过之后饼是从小到大堆起来的,结束时位置打印0。
解法:首先选择出最大的饼,如果它不在最下面,就把它发到最上面,然后整摞反过来,最大的饼就在最下面了。然后忽略最大的饼,又是在整摞饼中选择最大的饼(也就是原来的第二大的饼),重复以上过程,知道所有的饼都处理完了。
代码:
/*
uva 120 Stacks of Flapjacks
AC By Warteac
2013-4-15
Runtime:0.020s
*/
#include<iostream>
#include<vector>
#include<sstream>
#include<algorithm>
using namespace std;
//
class StacksOfFlapjacks{
private:
vector <int> pancake;
vector <int> index;//记录每次翻饼的位置
public:
void initial();
bool readCase();
void computing();
void outResult();
};
void StacksOfFlapjacks::initial(){
pancake.clear();
index.clear();
}
bool StacksOfFlapjacks::readCase(){
initial();
string str;
if(getline(cin,str) && str.length()){
cout << str <<endl;//将原数组输出,不能在outResult() 中输出,因为会改变
stringstream ss(str);
for(int i; ss >> i; pancake.push_back(i)) ; //新颖的写法,用空语句的for循环替代好几行的while循环
return true;
}else{
return false;
}
}
void StacksOfFlapjacks::computing(){
vector <int>:: iterator iMax,i; //迭代器的使用
//从最后一个位置开始遍历
for(i = pancake.end()-1; i >= pancake.begin() ; i--){ //最后一个元素的下标应该是end()-1
//cout<<"i = "<<*i<<endl; //用 *i 的方式取数据,相当于指针
iMax = max_element(pancake.begin(),i+1); //经过摸索得知函数的第二个参数是结束位置+1
//cout << "iMax = " <<*iMax <<endl;
//最大值不在应在的位置
if(iMax != i){
//最大值不在首位
if(iMax != pancake.begin()){
reverse(pancake.begin(),iMax+1); //同样结束位置+1
//for(int i = 0;i < pancake.size(); cout << pancake[i++] <<" ");
index.push_back(pancake.size()-(iMax - pancake.begin()));
//cout<<"index.push = "<< pancake.size()-(iMax - pancake.begin())<<endl;
}
//最大值已在首位,则翻转到应在的位置
reverse(pancake.begin(),i+1);
//for(int i = 0;i < pancake.size(); cout << pancake[i++] <<" ");
index.push_back(pancake.size()-(i- pancake.begin()));
//cout<<"index.push = "<<pancake.size()-(i- pancake.begin())<<endl;
}
}
}
void StacksOfFlapjacks::outResult(){
for(int i = 0;i < index.size(); cout << index[i++] <<" ");
cout << 0 <<endl;
}
//
int main(){
StacksOfFlapjacks sf;
while(sf.readCase()){
sf.computing();
sf.outResult();
}
return 0;
}