zoukankan      html  css  js  c++  java
  • [BZOJ1331]魔板

    Description
    在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板。这是一张有8个大小相同的格子的魔板:

    1 2 3 4
    8 7 6 5

    我们知道魔板的每一个方格都有一种颜色。这8种颜色用前8个正整数来表示。可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列。对于上图的魔板状态,我们用序列(1,2,3,4,5,6,7,8)来表示。这是基本状态。这里提供三种基本操作,分别用大写字母“A”,“B”,“C”来表示(可以通过这些操作改变魔板的状态):

    • “A”:交换上下两行;
    • “B”:将最右边的一列插入最左边;
    • “C”:魔板中央四格作顺时针旋转。

    下面是对基本状态进行操作的示范:
    A:

    8 7 6 5
    1 2 3 4

    B:

    4 1 2 3
    5 8 7 6

    C:

    1 7 2 4
    8 6 3 5

    对于每种可能的状态,这三种基本操作都可以使用。
    你要编程计算用最少的基本操作完成基本状态到目标状态的转换,输出基本操作序列。

    Input
    只有一行,包括8个整数,用空格分开(这些整数在范围 1——8 之间)不换行,表示目标状态。

    Output
    Line 1: 包括一个整数,表示最短操作序列的长度。
    Line 2: 在字典序中最早出现的操作序列,用字符串表示,除最后一行外,每行输出60个字符。

    Sample Input
    2 6 8 4 5 7 3 1

    Sample Output
    7
    BCABCCB


    直接上BFS,然后状态的话,用个struct存下这8个数的状态,状态的存法决定了转移方法。然后判断是否走过,用map,然后发现只要判断是否出现,那不如用下C++11的骚操作 unordered_set,学会了手打hash函数。。。否则这东西不能扔struct。。。

    /*program from Wolfycz*/
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<unordered_set>
    #define inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')    f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x>=10)	print(x/10);
    	putchar(x%10+'0');
    }
    const int N=5e4;
    const char s[3]={'A','B','C'};
    const int T[3][8]={
    	{7,6,5,4,3,2,1,0},
    	{1,2,3,0,7,4,5,6},
    	{0,2,5,3,4,6,1,7},
    };
    struct S1{
    	int val[8];
    	bool operator ==(const S1 &x)const{
    		for (int i=0;i<8;i++)	if (val[i]!=x.val[i])	return 0;
    		return 1;
    	}
    }h[N+10],tmp,Endl;
    struct myHash{
    	size_t operator ()(const S1 &x)const{
    		int res=0;
    		for (int i=0;i<8;i++)	res=(res<<3)+(res<<1)+x.val[i];
    		return(res);
    	}
    };
    int dis[N+10],opera[N+10],from[N+10];
    unordered_set<S1,myHash>st;
    int bfs(){
    	int head=1,tail=1;
    	for (int i=0;i<8;i++)	h[head].val[i]=i+1;
    	if (Endl==h[head])	return head;
    	st.insert(h[head]),dis[head]=0;
    	for (;head<=tail;head++){
    		for (int k=0;k<3;k++){
    			for (int i=0;i<8;i++)	tmp.val[T[k][i]]=h[head].val[i];
    			if (!st.count(tmp)){
    				st.insert(h[++tail]=tmp);
    				dis[tail]=dis[head]+1;
    				from[tail]=head;
    				opera[tail]=k;
    				if (tmp==Endl)	return tail;
    			}
    		}
    	}
    	return 0;
    }
    int stack[N+10];
    int main(){
    	for (int i=0;i<8;i++)	Endl.val[i]=read();
    	int T=bfs(),top=0,cnt=0;
    	printf("%d
    ",dis[T]);
    	while (T!=1)	stack[++top]=opera[T],T=from[T];
    	for (int i=top;i;i--){
    		printf("%c",s[stack[i]]),cnt++;
    		if (cnt==60){
    			putchar('
    ');
    			cnt=0;
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    iOS14
    iOS 音量键翻页实现
    pod 相关写法
    js 递归树结构数据查找指定元素的所有父级
    前端实现访问一个图片URL直接下载该图片
    HTML5 drag api 的使用
    vue 组件的 patch
    centos7安装nginx
    nginx常用配置说明
    遍历删除
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/9715202.html
Copyright © 2011-2022 走看看