[UVA120]Stacks of Flapjacks[STL][构造]

题目链接: [UVA120]Stacks of Flapjacks[STL][构造]
题意分析:给出一堆煎饼,你要做的就是把它们翻转成自顶向下,从小到大排序。每次可以进行的flips操作,flips(1)代表从底开始的第一个煎饼到顶的所有煎饼进行反转。即54321变成了12345(5是顶端,1是底端)。问怎么样把煎饼翻转成指定情况,输出所需要的flips操作。每个操作以0作为结尾,代表操作停止。输入保证没有相同大小的煎饼。
解题思路:有种冒泡排序的感觉,每次把最大的一个煎饼放到最底层,重复做这个动作直到达到目标。可以发现:对于任意一个煎饼,要想把它翻到底层,最多只需进行两次操作。例如12435。这次需要的就是把4放到底层,先进行flips(3),煎饼4就到达了顶端,然后flips(2),4就到底端了。根据这个思路,每次只需把找到煎饼,然后翻转就OK啦~我是用vector存的煎饼的。然后另开一个数组存煎饼,排序,以便后期查找煎饼。
个人感受:一开始觉得翻转什么的太麻烦了。正真动起手来其实也还好。(PS:突然发现没必要用vector存煎饼呀,呼呼,算了算了,就酱紫吧)

具体代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<sstream>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
int num[40];

int main()
{
	string s;
	while( getline(cin, s) )
	{
		vector<int> v;  //存煎饼 
		vector<int> ans; //存操作 
		stringstream ss(s);
		int x;
		int cnt = 0;
		while(ss >> x)
		{
			num[cnt] = x;
			++cnt;
			v.push_back(x);
		}
		sort(num, num + cnt); //排个序,然后每次找最大的煎饼进行翻转 
		for(int i = 0; i < v.size(); ++i)
		{
			if(i) cout << ' ';
			cout << v[i];
		}
		cout << '\n';
		for(int i = cnt - 1; i >= 0; --i)
		{
			for(int j = 0; j < i; ++j)
			{
				if(v[j] == num[i])
				{
					if(j == 0) //如果最大的煎饼就在第一个位置,一次翻转就能把它弄到底部 
					{
						ans.push_back(v.size() - i);
						reverse(v.begin(),v.begin() + i + 1);
					}
					else //否则要对同一煎饼翻转两次 
					{
						ans.push_back(v.size() - j);
						reverse(v.begin(),v.begin() + j + 1); 
						++i; //因为还没翻转到底部,所以不能进行下个煎饼的翻转 
					}
					break;
				}
			}
		}
		ans.push_back(0); //0作为结束 
		for(int i = 0; i < ans.size(); ++i)
		{
			if(i) cout << ' ';
			cout << ans[i];
		}
		cout << '\n';
	}
	return 0;
}


你可能感兴趣的:(vector,uva,构造)