现在的位置: 首页 > 综合 > 正文

蓝桥杯 九宫重排

2019年11月08日 ⁄ 综合 ⁄ 共 2037字 ⁄ 字号 评论关闭
康托展开式去重来一发bfs

#include<iostream>
#include<map>
#include<string>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int PermSize=9;
int factory[20]={0,1,2,6,24,120,720,5040,40320,362880,3628800,39916800};
bool used[362880];
char goal[9];
struct node
{
	int x,step;
	char s[9];
};
int cantor(const char* buf)
{
	int i,j,counted;
	int result=0;
	for(i=0;i<PermSize;++i)
	{
		counted=0;
		for(j=i+1;j<PermSize;++j)
			if(buf[i]>buf[j])
				++counted;
		result=result+counted*factory[PermSize-i-1];
	}
	return result;
}
void bfs(node st)
{
	int i,j,k;
	node now,next;
	queue<node>qq;
	qq.push(st);
	while(qq.size())
	{
		now=qq.front();
		qq.pop();
		i=now.x/3;
		j=now.x%3;
		if(i>0)
		{
			next.x=(i-1)*3+j;
			next.step=now.step+1;
			strcpy(next.s,now.s);
			swap(next.s[now.x],next.s[next.x]);
			k=cantor(next.s);
			if(!used[k])
			{
				qq.push(next);
				if(strcmp(next.s,goal)==0)
				{
					cout<<next.step;
					return;
				}
				used[k]=1;
			}
		}
		if(i<2)
		{
			next.x=(i+1)*3+j;
			next.step=now.step+1;
			strcpy(next.s,now.s);
			swap(next.s[now.x],next.s[next.x]);
			k=cantor(next.s);
			if(!used[k])
			{
				qq.push(next);
				if(strcmp(next.s,goal)==0)
				{
					cout<<next.step;
					return;
				}
				used[k]=1;
			}
		}
		if(j>0)
		{
			next.x=i*3+j-1;
			next.step=now.step+1;
			strcpy(next.s,now.s);
			swap(next.s[now.x],next.s[next.x]);
			k=cantor(next.s);
			if(!used[k])
			{
				qq.push(next);
				if(strcmp(next.s,goal)==0)
				{
					cout<<next.step;
					return;
				}
				used[k]=1;
			}
		}
		if(j<2)
		{
			next.x=i*3+j+1;
			next.step=now.step+1;
			strcpy(next.s,now.s);
			swap(next.s[now.x],next.s[next.x]);
			k=cantor(next.s);
			if(!used[k])
			{
				qq.push(next);
				if(strcmp(next.s,goal)==0)
				{
					cout<<next.step;
					return;
				}
				used[k]=1;
			}
		}
	}
	cout<<-1;
}
int main()
{
	node st;
	scanf("%s%s",st.s,goal);
	if(strcmp(st.s,goal)==0)
	{
		cout<<0;
		return 0;
	}
	st.step=0;
	st.x=strstr(st.s,".")-st.s;
	used[cantor(st.s)]=1;
	bfs(st);
	return 0;
}

http://lx.lanqiao.org/problem.page?gpid=T42
问题描述

  如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。

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

抱歉!评论已关闭.