zoukankan      html  css  js  c++  java
  • 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
     
    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
    ",nums);//测试
    120         cout<<str[nums]<<endl; //根据康托展开记录的数字查找
    121     }
    122 }
     
  • 相关阅读:
    华为摄像机sdc开发_02_华为摄像机到手后的一些问题
    华为摄像机sdc开发_01_基础开发环境搭建
    LNMP环境搭建及服务器加固
    常用数据库端口号
    Linux文件查找
    SpringBoot使用jackson
    Vue.js源码解析-Vue初始化流程之动态创建DOM
    Vue.js源码解析-Vue初始化流程
    Vue.js源码解析-从scripts脚本看vue构建
    Linux系统编程-文件IO
  • 原文地址:https://www.cnblogs.com/dshn/p/4948431.html
Copyright © 2011-2022 走看看