木块问题/The Blocks Problem(Uva 101)

扶醉桌前 提交于 2019-11-27 08:17:50

原题摘录

输入n,得到编号为0~n-1的木块,分别摆放在顺序排列编号为0~n-1的位置。现对这些木块进行操作,操作分为四种。

1、move a onto b:把木块a、b上的木块放回各自的原位,再把a放到b上;

2、move a over b:把a上的木块放回各自的原位,再把a发到含b的堆上;

3、pile a onto b:把b上的木块放回各自的原位,再把a连同a上的木块移到b上;

4、pile a over b:把a连同a上木块移到含b的堆上。

当输入quit时,结束操作并输出0~n-1的位置上的木块情况

输入输出见文末.

题目分析

每个木块堆的高度不确定,所以用vector来保存很合适;而每个木块堆的个数不超过n,所以用一个数组来存就可以了.

vector<int> pile[maxn];//一个存储int向量的数组

分析原题中的四个操作:

  归位 移顶
move a归位 均有-
onto b归位 且均为-
即move又onto a,b均归位 将a往b-
pile/over

发现这是个指令有很多共同点,根据这样编写的函数就会减少重复代码.也即一个归位函数和一个移顶函数以及查出位置的辅助函数.所以有时不用指令完全独立.

完整代码(详细注释)

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <assert.h>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>

using namespace std;
const int maxn = 30;
int n;
vector<int> pile[maxn];
 
//找到木块a所在的pile和height,以引用的形式返回调用者
void find_block(int a, int& p, int& h)//当有一个元素时高度为0,也即h=0
{
	for (p = 0; p < n;p++)
	for (h = 0; h < pile[p].size(); h++)
	{
		if (pile[p][h] == a)return;
	}
 
}
//把第p堆高度为h的木块上方的所有木块移回原位
void clear_above(int p, int h)
{
	for (int i = h + 1; i < pile[p].size(); i++)
	{
		int m = pile[p][i];
		pile[m].push_back(m);
	}
	pile[p].resize(h + 1);
 
}
//把第p堆高度为h及其上方的木块整体移动到p2堆的顶部
void pile_onto(int p, int h,int p2)
{
	for (int i = h; i < pile[p].size(); i++)
		pile[p2].push_back(pile[p][i]);
	pile[p].resize(h);
 
}
 
void print()
{
	for (int i = 0; i < n; i++)
	{
		printf("%d:", i);
		for (int j = 0; j < pile[i].size(); j++)
			printf(" %d", pile[i][j]);
		printf("\n");
 
	}
}
 
 
int main()
{
	int a, b;
	cin >> n;
	string s1, s2;
	for (int i = 0; i < n; i++)pile[i].push_back(i);
	while (cin >> s1 >> a >> s2 >> b)//cin >> s1&&s1 != "quit"&&cin >> a >> s2 >> b
	{
		int pa, pb, ha, hb;
		find_block(a, pa, ha);//找到a所在的位置:pa指第几个vector-1,ha指该vector的长度-1
		find_block(b, pb, hb);
		if (pa == pb) continue;//非法指令
		if (s2 == "onto") clear_above(pb, hb);//b归位
		if (s1 == "move") clear_above(pa, ha);//a归位
		pile_onto(pa, ha, pb);
 
	}
	print();
	
	return 0;
}

附如果关于位置又不太明白的,可以仅使用find_block()函数输出一下看看:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <assert.h>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
using namespace std;
const int maxn = 30;
int n;
vector<int> pile[maxn]; 
//找到木块a所在的pile和height,以引用的形式返回调用者
void find_block(int a, int& p, int& h)
{
	for (p = 0; p < n;p++)
	for (h = 0; h < pile[p].size(); h++)
	{
		if (pile[p][h] == a)return;
	}
 
} 
int main()
{
	int a, b;
	cin >> n;
	for (int i = 0; i < n; i++)pile[i].push_back(i);
	cin >> a >>  b;
	int pa, pb, ha, hb;
	find_block(a, pa, ha);
	find_block(b, pb, hb);	
	cout<<"pa:"<<pa<<" "<<"ha:"<<ha<<endl;
	cout<<"pb:"<<pb<<" "<<"hb:"<<hb<<endl;
	return 0;
}
//https://www.cnblogs.com/QG-whz/

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!