Bootstrap

The Blocks Problem

题目是PDF文档的,这里就不阐述题目内容了,不知道内容的朋友可以移步:

https://www.luogu.com.cn/problem/UVA101

思路阐述

(1)可以观察到题目的时间限制为3.00s,n的取值范围为(0,25),那么我们就不用担心时间超限的问题了,而题目涉及到四种操作,我们就可以明白:这是一道模拟题。

(2)观察四种操作不难发现:四种操作都可以归纳为先清除,再叠放。既然这样,我们就可以设置两个函数完成操作。

void Clear(int index,int n);  //清楚第 index 个块头顶的所有块

void fun(int index,int index2, int n);   //将第 index 个块移到第 index2 上

(3)函数我们有了,那么就要来考虑怎么表示第 index 个块的位置。我们可以这样想,题目最后要求的是第 index 块所在的位置,那么我们用 into 来表示其去往的位置,用height表示其在into的哪个高度上。同时因为 Clear() 的存在且最终题目要输出的是其原本的为第几块,那么我们用 first 代表其初始位置,即其为第 first(index) 块。最后我们要考虑怎么把结果输出,因为题目要求输出从零到n-1上存在的按从低到高输出的块名称,那我们就可以先从小到大排列into,相同into则从小到大排列height。我们可以用一个结构体来包含这三个数及排列运算:

struct Node
{
    int into, height, first;
    bool operator<(Node b)
    {
        if (b.into == into) return height < b.height;
        else return into < b.into;
    }
};

 那么请让我为你献上代码

#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
struct Node
{
	int into, height, first;
	bool operator<(Node b)
	{
		if (b.into == into) return height < b.height;
		else return into < b.into;
	}
}node[25];
void init(int n)
{
	for (int i = 0; i < n; i++)
	{
		node[i].into = node[i].first = i;
		node[i].height = 1;
	}
}
void Clear(int index,int n)  //清楚第 index 个块头顶的所有块
{
	int into = node[index].into,height=node[index].height;
	for (int i = 0; i < n; i++)
	{
		if (node[i].into == into&&node[i].height>height) node[i].into = node[i].first;
	}
}
void fun(int index,int index2, int n)  //将第 index 个块移到第 index2 上
{
	int into1 = node[index].into, into2 = node[index2].into;
	int height = 1;
	int height1 = node[index].height;
	for (int i = 0; i < n; i++) if (into2 == node[i].into&&node[i].height>height) height = node[i].height;
	for (int i = 0; i < n; i++) if (into1 == node[i].into&&node[i].height >= height1) { node[i].into = into2; node[i].height = node[i].height - height1 + 1 + height; }
}
int main()
{
	int n,a,b;
	string str1, str2;
	cin >> n;
	init(n);
	while (cin >> str1)
	{
		if (str1 == "quit") break;
		cin >> a >> str2 >> b;
		if (a == b || node[a].into == node[b].into) continue;
		if (str1 == "move"&&str2 == "onto")
		{
			Clear(a, n);
			Clear(b, n);
			fun(a, b, n);
		}
		if (str1 == "move"&&str2 == "over")
		{
			Clear(a, n);
			fun(a, b, n);
		}
		if (str1 == "pile"&&str2 == "onto")
		{
			Clear(b, n);
			fun(a, b, n);
		}
		if (str1 == "pile"&&str2 == "over")
		{
			fun(a, b, n);
		}
	}
	sort(node, node + n);
	int flag = 0;
	for (int i = 0; i < n; flag++)
	{
		while (flag < node[i].into) cout << flag++ << ":" << endl;
		cout << flag << ':';
		while (i<n&&flag == node[i].into) cout << ' ' << node[i++].first;
		cout << endl;
	}
	while (flag<n) cout << flag++ << ":" << endl;
}

;