九宫重排



历届试题 九宫重排  时间限制:1.0s   内存限制:256.0MB       锦囊1锦囊2锦囊3问题描述  如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。


  我们把第一个图的局面记为:12345678.
  把第二个图的局面记为:123.46758
  显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
  本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。输入格式  输入第一行包含九宫的初态,第二行包含九宫的终态。输出格式  输出最少的步数,如果不存在方案,则输出-1。样例输入12345678.
123.46758样例输出3样例输入13524678.
46758123.样例输出22




这道题目用了字典树来判重;
刚开始做的时候把数组开成了9,大意了,以后一定看清楚数组范围;




#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
using namespace std;

typedef struct node 
{
	int d;
	struct node*next[9];
}Node;

typedef struct 
{
	int step;
	char str[10];
}M;

Node *head;
queue<M> q;
int dir[4] = {-1, 1, 3, -3}, f;
char a[10], b[10];

void init_node(Node **p, int j)
{
	int i;
	*p = (Node *)malloc(sizeof(Node));
	(*p)->d = j;
	for(i = 0; i < 9; i++)
	{
		(*p)->next[i] = NULL;
	}
}

int create_tree(char *a)
{
	Node *p, *temp = head;
	int i, flag = 1,j;
	for(i = 0; i < 9;i++)
	{
		if(a[i] == '.')
		{
			j = 0;
		}
		else
		{
			j = a[i] - 48;
		}
		if( !temp->next[j])//如果j这个值在树中没有那么这整个值就没有出现过;创建结点把这个值存入树中; 
		{
			flag = 0;
			init_node(&p, j);
			temp->next[j] = p;
		}
		temp = temp->next[j];
	}
	return flag;//flag为0说明这个状态没有出现过; 
}

int get_pos(char *a)
{
	int i;
	for(i = 0; i < 9; i++)
	{
		if(a[i] == '.')
		{
			return i;
		}
	}
}

void bfs()
{
	int i, pos,npos, j;
	M p, t;
	while(!q.empty())
	{
		p = q.front();
		q.pop();
		pos = get_pos(p.str);
		if(strcmp(p.str,b)== 0)
		{
			f = 1;
			printf("%d\n", p.step);
			return;
		}
		for(i = 0 ;i < 4; i++)
		{
			
			if((pos % 3 == 0&& dir[i] == -1) || (pos %3 == 2 && dir[i] == 1))
			{
				continue;
			}
			npos = pos + dir[i];
			if(npos < 0 || npos > 8)
			{
				continue;
			}
			strcpy(t.str, p.str);
			t.str[pos] = t.str[npos];
			t.str[npos] = '.';
			j = create_tree(t.str);
			if(j == 0)
			{
				t.step = p.step + 1;
				if(memcmp(t.str,b,sizeof(b))== 0)
				{
					f = 1;
					printf("%d\n", t.step);
					return;
				}
				q.push(t);
			}
		}
	}
	
}

int main()
{
	M p; 
	int i,j;
	
	while(scanf("%s %s", a,b) != EOF)
	{
		f = 0;
		while(!q.empty())
		{
			q.pop();
		}
		init_node(&head, 0);
		j = create_tree(a);
		strcpy(p.str,a);
		p.step = 0;
		q.push(p);
		bfs();
		if(f == 0)
			printf("-1\n");
	}
	return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值