UVa101 - The Blocks Problem

桌上放有若干“blocks”

    

\begin{figure}\centering\setlength{\unitlength}{0.0125in} %\begin{picture}(2......raisebox{0pt}[0pt][0pt]{$\bullet\bullet \bullet$ }}}\end{picture}\end{figure}
Figure: Initial Blocks World

初始位置如图所示;有五种操作:

(1)move a onto b :先将a和b之上的所有block都复位(恢复为initial状态),然后把a放在b上;

(2)move a over b :先将a之上的所有block都复位,然后把a放在b所在的堆顶端;

(3)pile a onto b :先将b之上的所有block都复位,然后把a以及a之上的所有block放在b之上;

(4)pile a over b :将a以及a之上所有的block放在b所在的堆顶端

(5)quit :退出

Sample Input 

10
move 9 onto 1
move 8 over 1
move 7 over 1
move 6 over 1
pile 8 over 6
pile 8 over 5
move 2 over 1
move 4 over 9
quit


Sample Output 

 0: 0
 1: 1 9 2 4
 2:
 3: 3
 4:
 5: 5 8 7 6
 6:
 7:
 8:
 9:

解题思路:

        应该用链表来做,我用数组模拟了链表,因为觉得指针容易出错。

代码:

#include <string.h>
#include <stdio.h>

#define MAXNUM 25
typedef struct
{
	int adress ;
	int start ;
	int pre ;
	int next ;
} BlockType ;

BlockType arr[MAXNUM];

void resetinit(int from)
{
	int q ;
	int p = arr[from].next ;
	arr[from].next = -1 ;
	while(p != -1)
	{
		arr[p].adress = p ;
		arr[p].start = p ;
		arr[p].pre = -1 ;
		q = arr[p].next ;
		arr[p].next = -1 ;
		p = q ;
	}
}

int main()
{
	int T ;
	scanf("%d" , &T) ;
	for(int i = 0 ; i < T ; i ++)
	{
		arr[i].start = i ;
		arr[i].adress = i ;
		arr[i].next = -1 ;
		arr[i].pre = -1 ;
	}

	char cmd1[10],cmd2[10];
	int pmt1,pmt2;
	while(scanf("%s" , cmd1))
	{
		if(! strcmp(cmd1,"quit"))
			break ;
		scanf("%d%s%d" , &pmt1 , cmd2 , &pmt2) ;

		int cmd ;
		if(! strcmp(cmd1,"move"))
		{
			if(! strcmp(cmd2,"onto"))
				cmd = 1 ;
			else
				cmd = 2 ;
		}
		else
		{
			if(! strcmp(cmd2,"onto"))
				cmd = 3 ;
			else
				cmd = 4 ;
		}

		int p,q ;
		switch(cmd)
		{
		case 1 : 
			if(arr[pmt1].adress == arr[pmt2].adress)
				break ;
			resetinit(pmt1);
			resetinit(pmt2);

			if(arr[pmt1].pre != -1)
			{
				p = arr[pmt1].pre ;
				arr[p].next = -1 ;
			}
			else
			{
				p = arr[pmt1].adress ;
				arr[p].start =  -1;
			}

			arr[pmt1].adress = arr[pmt2].adress ;

			arr[pmt1].pre = pmt2 ;
			arr[pmt2].next = pmt1 ;

			break ;

		case 2 :
			if (arr[pmt1].adress == arr[pmt2].adress)
				break ;
			resetinit(pmt1);

			if(arr[pmt1].pre != -1)
			{
				p = arr[pmt1].pre ;
				arr[p].next = -1 ;
			}
			else
			{
				p = arr[pmt1].adress ;
				arr[p].start =  -1;
			}

			arr[pmt1].adress = arr[pmt2].adress ;

			p = pmt2 ;
			while(p != -1)
			{
				q = p ;
				p = arr[p].next ;
			}

			arr[q].next = pmt1 ;
			arr[pmt1].pre = q ;



			break;

		case 3 : 
			if (arr[pmt1].adress == arr[pmt2].adress)
				break ;

			resetinit(pmt2);

			p = arr[pmt1].pre ;
			if(p != -1)
			{
				arr[p].next = -1 ;
			}
			else
			{
				q = arr[pmt1].adress ;
				arr[q].start = -1 ;
			}

			p = pmt1 ;
			while(p != -1)
			{
				arr[p].adress = arr[pmt2].adress ;
				p = arr[p].next ;
			}

			arr[pmt2].next = pmt1 ;
			arr[pmt1].pre = pmt2 ;

			break;

		case 4 : 
			if (arr[pmt1].adress == arr[pmt2].adress)
				break ;

			p = arr[pmt1].pre ;
			if(p != -1)
			{
				arr[p].next = -1 ;
			}
			else
			{
				q = arr[pmt1].adress ;
				arr[q].start = -1 ;
			}

			p = pmt1 ;
			while(p != -1)
			{
				arr[p].adress = arr[pmt2].adress ;
				p = arr[p].next ;
			}

			p = pmt1 ;
			q = pmt2 ;
			while(arr[q].next != -1)
			{
				q = arr[q].next ;
			}

			arr[q].next = p ;
			arr[p].pre = q ;

			break;
		}
	}

	for(int i = 0 ; i < T ; i ++)
	{
		printf("%d:" , i) ;
		int tmp = arr[i].start ;
		while(tmp != -1)
		{
			printf(" %d" , tmp) ;
			tmp = arr[tmp].next ;
		}
		printf("\n") ;
	}

	return 0 ;
}
安静CT说用了cin,cout,又是c语言风格,乱七八糟的……苦口婆心劝说下,老老实实改成了scanf和printf,结果AC的时间减少了0.004~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值