UVA-101 The Blocks Problem

2016-08-18

UVA - 101 The Blocks Problem

题目大意:操作积木。有 0~n-1 个积木,初始状态是并排横放。有四种操作:move a onto b,将 a、b 上的方块放回原位然后将 a 放在 b 上;move a over b,将 a 上的方块放回原味然后将 a 放在 b 所在位置的最顶上;pile a onto b,将 b 上的方块放回原味然后将 a 及其上所有的方块放到 b 上;pile a over b,将 a 及其上所有方块放到 b 所在的位置最顶上。

解题思路:开个二维数组模拟就好,这种题目把最小的动作分解出来组合就好了。

注意:这题主要是要注意一些小细节,一直WA。。。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

int map[50][50];
char str[2][20];
int a, b;

void find(int x) {
	for (int i = 0; i < 25; i++)
		for (int j = 0; j < 25; j++)
			if ( map[i][j] == x ) {
				a = i;
				b = j;
			}
}

void del(int x) {
	find(x);
	for (int i = b; i < 25; i++)
        map[a][i] = -1;
}

void re(int x) {
	find(x);
	for (int i = b+1; i < 25; i++)
		if ( map[a][i] != -1 ) {
			int tmp = map[a][i];
			map[tmp][0] = tmp;
			map[a][i] = -1;
		}
}

void move_onto(int x, int y) {
	re(x);
	re(y);
	find(x);
	map[a][b] = -1;
	find(y);
	map[a][b+1] = x;
}

void move_over(int x, int y) {
	re(x);
	del(x);
	find(y);
	for (int i = b; i < 25; i++)
		if ( map[a][i] == -1) {
			map[a][i] = x;
			break;
		}
}

void pile_onto(int x, int y) {
	re(y);
	find(x);
	int tmp[50];
	int j = 0;
	for (int i = b; map[a][i] != -1; i++)
		tmp[j++] = map[a][i];
	int tag = j;
	del(x);
	find(y);
	j = 0;
	for (int i = b; j < tag; i++)
		if ( map[a][i] == -1 )
			map[a][i] = tmp[j++];
}

void pile_over(int x, int y) {
	find(x);
	int tmp[50];
	int j = 0;
	for (int i = b; map[a][i] != -1; i++)
		tmp[j++] = map[a][i];
	int tag = j;
	del(x);
	find(y);
	j = 0;
	for (int i = b; j < tag; i++)
		if ( map[a][i] == -1 ) 
			map[a][i] = tmp[j++];
}	

int main() {
	int n;
	int c, d;
	scanf("%d", &n);
	memset(map, -1, sizeof(map));
	for (int i = 0; i < n; i++)
		map[i][0] = i;
	while (	scanf("%s", str[0]) ) {
		if ( !strcmp(str[0], "quit") )
			break;
		scanf("%d%s%d", &c, str[1], &d);
		find(c);
		int x1 = a;
		find(d);
		int x2 = a;
		if ( x1 == x2 )
			continue;
		if ( !strcmp(str[0], "move") && !strcmp(str[1], "onto") )
			move_onto(c, d);
		if ( !strcmp(str[0], "move") && !strcmp(str[1], "over") )
			move_over(c, d);
		if ( !strcmp(str[0], "pile") && !strcmp(str[1], "onto") )
			pile_onto(c, d);
		if ( !strcmp(str[0], "pile") && !strcmp(str[1], "over") )
			pile_over(c, d);
	}
	for (int i = 0; i < n; i++) {
		cout << i << ":";
		for (int j = 0; map[i][j] != -1; j++)
			cout << " " << map[i][j];
		cout << endl;
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值