UVa 101 - The Blocks Problem解题报告

这篇博客详细介绍了在解决UVa 101 - The Blocks Problem时的思路和过程。作者强调这是一道对细心程度要求极高的模拟题,通过调试,作者学习到了不少调试技巧。题目中无需考虑将积木放回原位时的特殊情况,因为不可能存在某个操作能将积木放置到空位置。解题方法是使用二维数组和结构数组来模拟积木堆,同时跟踪每个积木的位置和每个堆的长度,然后实现四个操作的模拟。
摘要由CSDN通过智能技术生成

模拟类型的题,很麻烦。特别考验细心程度。虽然调试了很久,但是倒也学会了不少的调试技巧。

注意:无需考虑将积木放回原位时原位被占的情况,因为没有任何一个操作可以把积木放在空的位置上,因此也不可能出现在第i个位置上,第i个积木的下面有其它积木的情况。

思路:用一个二维数组模拟积木堆,用结构数组pos存储每个积木的x,y坐标,每个积木的代号正好与结构数组的下标形成一一映射。再用len数组存储存储每个堆的长度。接着就是模拟四个操作了。


//101 - The Blocks Problem
#include <iostream>
#include <cstring>
#include <assert.h>
using namespace std;
struct coord
{
	int x, y;
};
int stacks[30][30], len[30];
coord pos[30];
void over(char *, int, int);
void onto(char *, int, int);
void back(int);
void print(int);
int main()
{
	//freopen("data.txt", "r", stdin);
	int n;
	scanf("%d", &n);
	getchar();
	for(int i = 0; i < n; i++)//初始化
		stacks[i][0] = i, len[i] = 1, pos[i].x = i, pos[i].y = 0;
	char str[50];
	while (cin.getline(str, 50))
	{
		if(str[0] == 'q')
			break;
		char a[5], b[5];
		int x1, x2;
		sscanf(str, "%[^ ] %d %[^ ] %d", a, &x1, b, &x2);//
		if(pos[x1].x == pos[x2].x)
			continue;
		if(strcmp(b, "onto") == 0)
			onto(a, x1, x2);
		else
			over(a, x1, x2);
	//	print(n);
	}
	print(n);

	return 0;
}

void onto(char *s, int x1, int x2)
{
	if(strcmp(s, "move") == 0)
	{
		back(x1);//清除上层的积木
		back(x2);
		const int  W1 = pos[x1].x, W2 = pos[x2].x, H1 = pos[x1].y, H2 = pos[x2].y;
		stacks[W2][len[W2]++] = x1;//增加积木和长度
		len[W1]--;//减少长度
		stacks[W1][len[W1]] = -1;//删除积木
		pos[x1].x = pos[x2].x;//更新位置
		pos[x1].y = pos[x2].y + 1;
		
	}
	else
	{
		back(x2);
		const int  W1 = pos[x1].x, W2 = pos[x2].x, H1 = pos[x1].y, H2 = pos[x2].y, max = len[W1];
		for(int i = H1; i < max; i++)
		{
			stacks[W2][len[W2]++] = stacks[W1][i];//增加积木
			pos[stacks[W1][i]].x = pos[x2].x;//更新位置
			pos[stacks[W1][i]].y = H2 + i - H1 + 1;//更新高度
			len[W1]--;//
			stacks[W1][i] = -1;//删除积木
		}
	}
}

void over(char *s, int x1, int x2)
{
	if(strcmp(s, "move") == 0)
	{
		back(x1);
		const int  W1 = pos[x1].x, W2 = pos[x2].x, H1 = pos[x1].y, H2 = pos[x2].y;
		stacks[W2][len[W2]++] = x1;
		len[W1]--;//减少长度
		stacks[W1][len[W1]] = -1;//删除积木
		pos[x1].x = pos[x2].x;//更新位置
		pos[x1].y = len[W2] - 1;//更新高度
		
	}
	else
	{
		const int  W1 = pos[x1].x, W2 = pos[x2].x, H1 = pos[x1].y, Hmax = len[W2] - 1, max = len[W1];
		for(int i = H1; i < max; i++)
		{
			stacks[W2][len[W2]++] = stacks[W1][i]; //增加积木
			pos[stacks[W1][i]].x = pos[x2].x;//更新位置
			pos[stacks[W1][i]].y = Hmax + i - H1 + 1;//更新高度
			len[W1]--;
			stacks[W1][i] = -1;
		}
		
		
	}
}

void back(int n)
{
	const int W = pos[n].x, H = pos[n].y, max = len[W];
	for(int i = H + 1; i < max; i++)//遍历n上面的积木
	{
		pos[stacks[W][i]].x = stacks[W][i];//其原位置就是本身的值
		pos[stacks[W][i]].y = 0;//更新高度
		stacks[stacks[W][i]][0] = stacks[W][i];//移回原位
		len[stacks[W][i]]++;//这里忘了加长
		stacks[W][i] = -1;//删除积木
		len[W]--;

	}
}

void print(int n)
{
	for(int i = 0; i < n; i++)
	{
		printf("%d:", i);
		for(int j = 0; j < len[i]; j++)
			printf(" %d", stacks[i][j]);
		printf("\n");
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值