hdu1430魔板(广搜+康托展开+string应用)

魔板

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2420    Accepted Submission(s): 511

Problem Description

在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板。魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示。任一时刻魔板的状态可用方块的颜色序列表示:从魔板的左上角开始,按顺时针方向依次写下各方块的颜色代号,所得到的数字序列即可表示此时魔板的状态。例如,序列(1,2,3,4,5,6,7,8)表示魔板状态为:

1 2 3 4
8 7 6 5

对于魔板,可施加三种不同的操作,具体操作方法如下:

A: 上下两行互换,如上图可变换为状态87654321
B: 每行同时循环右移一格,如上图可变换为41236785
C: 中间4个方块顺时针旋转一格,如上图可变换为17245368

给你魔板的初始状态与目标状态,请给出由初态到目态变换数最少的变换步骤,若有多种变换方案则取字典序最小的那种。

Input

每组测试数据包括两行,分别代表魔板的初态与目态。

Output

对每组测试数据输出满足题意的变换步骤。

Sample Input

12345678

17245368

12345678

82754631

Sample Output

C

AC

Author

LL

Source

ACM暑期集训队练习赛(三)

Recommend

linle   |   We have carefully selected several similar problems for you:  1429 1426 1427 1401 1043

  1 #include<iostream>
  2 #include <cstdio>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include <string>//定义string类型的变量是需要头文件
  6 #include<queue>
  7 using namespace std;
  8 char a[10],b[10];
  9 int visit[50000];
 10 int f[10]= {1,1,2,6,24,120,720,5040}; //1-7的阶层,康托展开需要用到
 11 string str[500000];  //存放康托展开的变换过程
 12 struct node
 13 {
 14     char num[8];//记录当前字符串
 15     int ct;//记录康托值
 16 };
 17 node node1,node2;
 18
 19 void way(int k)//将12345678经过0,1,2三种变换方式
 20 {
 21     if(k==0)//87654321
 22     {
 23         for(int i=0; i<4; i++)
 24         {
 25             node2.num[i]=node1.num[7-i];
 26             node2.num[i+4]=node1.num[3-i];
 27         }
 28     }
 29     else if(k==1)//41236785
 30     {
 31         node2.num[0]=node1.num[3];
 32         node2.num[7]=node1.num[4];
 33         for(int i=1; i<4; i++)
 34         {
 35             node2.num[i]=node1.num[i-1];
 36             node2.num[i+3]=node1.num[i+4];
 37         }
 38     }
 39     else//17245368
 40     {
 41         node2.num[0]=node1.num[0];
 42         node2.num[1]=node1.num[6];
 43         node2.num[2]=node1.num[1];
 44         node2.num[3]=node1.num[3];
 45         node2.num[4]=node1.num[4];
 46         node2.num[5]=node1.num[2];
 47         node2.num[6]=node1.num[5];
 48         node2.num[7]=node1.num[7];
 49     }
 50 }
 51 //康托展开的公式是 X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0! 其中,ai为当前未出现的元素中是排在第几个(从0开始)
 52 int kangtuo(char ch[]) //计算康托展开的数字,方法详见“康托展开”博客
 53 {
 54     int s=0,w;
 55     for(int i=0; i<8; i++)
 56     {
 57         w=0;
 58         for(int j=i+1; j<8; j++)
 59         {
 60             if(ch[j]<ch[i])
 61                 w++;
 62         }
 63         s+=w*f[7-i];
 64     }
 65     return s;
 66 }
 67 void bfs()
 68 {
 69
 70     int n;
 71     char c;
 72     queue<node> q;
 73     while(!q.empty())
 74         q.pop();
 75
 76     strcpy(node1.num,"12345678");//起始状态虽然不是12345678,但是可以把它看做12345678
 77     node1.ct=0;//初始康托值为0
 78     memset(visit,0,sizeof(visit));
 79     visit[0]=1;
 80     str[0]="";
 81     q.push(node1);
 82     while(!q.empty())
 83     {
 84         node1=q.front();
 85         q.pop();
 86         for(int i=0; i<3; i++)
 87         {
 88             way(i);//变换后的字符记录在node2.num上
 89             n=kangtuo(node2.num);//此时的康托值
 90             if(!visit[n])//通过判断康托值是否出现以此记录这个串是否出现
 91             {
 92                 visit[n]=1;//这个康托值标记为已出现
 93                 c=‘A‘+i; //变换的方案
 94                 node2.ct=n;//保存当前串的康托值
 95                 str[n]=str[node1.ct]+c; //记录变换过程
 96                 q.push(node2);
 97             }
 98         }
 99     }
100 }
101 int main()
102 {
103     char ch[10];
104     int nums;
105     bfs();//预处理打表
106     while(~scanf("%s%s",a,b))
107     {
108         for(int i=0; i<8; i++)
109         {
110             ch[a[i]-‘0‘]=i+1+‘0‘;//建立对应关系,记录起始数据每个数的位置,必须借用ch[]保存
111         }
112         for(int j=0; j<8; j++)
113         {
114             b[j]=ch[b[j]-‘0‘];//置换,利用位置变换形成新的字符串
115         }
116         // for(int k=0;k<8;k++)//测试
117         // printf("%d",b[k]);
118         nums=kangtuo(b);//计算康托展开的数
119         //  printf("%d\n",nums);//测试
120         cout<<str[nums]<<endl; //根据康托展开记录的数字查找
121     }
122 }
时间: 2024-11-03 21:54:52

hdu1430魔板(广搜+康托展开+string应用)的相关文章

hdu1430魔板

Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜色序列表示:从魔板的左上角开始,按顺时针方向依次写下各方块的颜色代号,所得到的数字序列即可表示此时魔板的状态.例如,序列(1,2,3,4,5,6,7,8)表示魔板状态为: 1 2 3 48 7 6 5 对于魔板,可施加三种不同的操作,具体操作方法如下: A: 上下两行互换,如上图可变换为状

HDU-1430 魔板

BFS+预处理. 一组解的话Usaco有题...要是T组解的话就预处理一下. #include <cstdio> #include <iostream> #include <fstream> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #define rep(i, l,

康托展开及其逆运算 详解

前文: 这个东东是我准备进攻一道A*算法的八数码题目时,遇到的. 决定先搞懂这个,再进攻八数码(传说中  不做人生不完整的 题目). 康托展开是什么? 定义: X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0! ai为整数,并且0<=ai<i(1<=i<=n) 简单点说就是,判断这个数在其各个数字全排列中从小到大排第几位. 比如 132,在1.2.3的全排列中排第2位. 康托展开有啥用呢? 维基:n位(0~n-1)全排列后,其

sicily 2011. Nine Digits(广搜,康托展开)

2011. Nine Digits Constraints Time Limit: 2 secs, Memory Limit: 256 MB Description Nine tiles, each with a number from 1 to 9 on it, are packed into a 3 by 3 frame. Your task is to arrange the tiles so that they are ordered as: 1 2 3 4 5 6 7 8 9 At e

Sicily 1151 解题报告(魔板,广搜)

      I.     原题中文大意 魔板由2*4个方块组成,用1到8的数字表示不同的块. 其初始状态是 1 2 3 4 8 7 6 5 对魔板可进行三种基本操作,这三种基本操作,可将任一种状态装换成另一种状态. A (上下行互换) B (行循环右移一格) C (中间四块顺时针转90) 8 7 6 5 1 2 3 4 4 1 2 3 5 8 7 6 1 7 2 4 8 6 3 5 II.       算法思想及解题用到的主要数据结构 广度优先搜索,已搜索过的节点不再进行记录,保证第一个找到的解

ACM-康托展开+预处理BFS之魔板——hdu1430

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1679    Accepted Submission(s): 354 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版--魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜

HDU 1430 魔板(康托展开+BFS+预处理)

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2921    Accepted Submission(s): 649 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜

hdu.1430.魔板(bfs + 康托展开)

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2170    Accepted Submission(s): 455 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜

魔板 Magic Squares(广搜,状态转化)

题目背景 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 题目描述 我们知道魔板的每一个方格都有一种颜色.这8种颜色用前8个正整数来表示.可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列.对于上图的魔板状态,我们用序列(1,2,3,4,5,6,7,8)来表示.这是基本状态. 这里提供三种基本操作,分别用大写字母“A”,“B”,“C”来表示(可以通过这些操作改