UVa Problem 120 Stacks of Flapjacks (煎饼堆)

// Stacks of Flapjacks (煎饼堆)
// PC/UVa IDs: 110402/120, Popularity: B, Success rate: high Level: 2
// Verdict: Accepted
// Submission Date: 2011-05-22
// UVa Run Time: 0.028s
//
// 版权所有(C)2011,邱秋。metaphysis # yeah dot net
//
// 先将数据排序,然后根据排序后的结果将原来的序列进行相应操作变成最终的序列。在排序时,由于可能有
// 两个饼具有相同的直径,故需要记录数据的序号,恢复的方法是找到当前尚未排序的X,先将其翻转到顶端,
// 然后再翻转到其在最终排序后的位置。
	
#include <iostream>
#include <sstream>
#include <algorithm>
	
using namespace std;
	
#define MAXSIZE 30
	
struct pancake
{
	int diameter;
	int index;
};
	
pancake pancakes[MAXSIZE];
pancake original[MAXSIZE];
	
bool cmp(pancake x, pancake y)
{
	return x.diameter < y.diameter;
}
	
void flip(int pos, int size)
{
	pancake tmp;
	int i = 0, j = size - pos;
	for (; i < j; i++, j--)
		if (original[i].diameter != original[j].diameter)
		{
			tmp = original[i];
			original[i] = original[j];
			original[j] = tmp;
		}
}
	
int main(int ac, char *av[])
{
	string line;
	while (getline(cin, line))
	{
		// 回显。
		cout << line << endl;
	
		// 读入数据。
		int capacity = 0;
		istringstream iss(line);
		while (iss >> pancakes[capacity].diameter)
		{
			pancakes[capacity].index = capacity;
			original[capacity] = pancakes[capacity];
			capacity++;
		}
	
		// 排序。
		sort(pancakes, pancakes + capacity, cmp);
	
		// 执行翻转操作,若第 i 大元素未在第i位上,则先找到其序号,然后
		// 先将其翻转到顶端,然后再翻转到位置i。
		for (int i = capacity - 1; i >= 0; i--)
		{
			// 在当前序列中找到该元素。
			// 假如数原来的序号与当前的序号不等,需要翻转操作。
			int marker;
			for (int j = 0; j < capacity; j++)
				if (original[j].index == pancakes[i].index)
				{
					marker = j;
					break;
				}
	
			if (marker != i)
			{
				if (marker != 0)
				{
					cout << (capacity - marker) << " ";
					flip(capacity - marker, capacity);
				}

				cout << (capacity - i) << " ";
				flip(capacity - i, capacity);
			}
		}
	
		cout << "0" << endl;
	}
	
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值