• USACO3.2.5Magic Squares


    Magic Squares
    IOI'96

    Following the success of the magic cube, Mr. Rubik invented its planar version, called magic squares. This is a sheet composed of 8 equal-sized squares:

    1 2 3 4
    8 7 6 5

    In this task we consider the version where each square has a different color. Colors are denoted by the first 8 positive integers. A sheet configuration is given by the sequence of colors obtained by reading the colors of the squares starting at the upper left corner and going in clockwise direction. For instance, the configuration of Figure 3 is given by the sequence (1,2,3,4,5,6,7,8). This configuration is the initial configuration.

    Three basic transformations, identified by the letters `A', `B' and `C', can be applied to a sheet:

    • 'A': exchange the top and bottom row,
    • 'B': single right circular shifting of the rectangle,
    • 'C': single clockwise rotation of the middle four squares.

    Below is a demonstration of applying the transformations to the initial squares given above:

    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

    All possible configurations are available using the three basic transformations.

    You are to write a program that computes a minimal sequence of basic transformations that transforms the initial configuration above to a specific target configuration.

    PROGRAM NAME: msquare

    INPUT FORMAT

    A single line with eight space-separated integers (a permutation of (1..8)) that are the target configuration.

    SAMPLE INPUT (file msquare.in)

    2 6 8 4 5 7 3 1 
    

    OUTPUT FORMAT

    Line 1: A single integer that is the length of the shortest transformation sequence.
    Line 2: The lexically earliest string of transformations expressed as a string of characters, 60 per line except possibly the last line.

    SAMPLE OUTPUT (file msquare.out)

    7
    BCABCCB
    题解:看到此题,果断想到了The Clocks的方法,然后速度写了个DFS,写完才发现步数要最短(以后还是要认真看题呀,这次就是教训!!!),所以我就记录了一下最优解。不过深度达到15就超时了。。。只能推到重来,用BFS写。当然肯定要判重,减少拓展节点,避免重复拓展同一状态,不然还是得超时,如果开个87654321大的hash数组会超内存,所以这样还是行不通,只好去看题解,题解上是用康托展开。所以我就去学习了下康托展开。主要看的是网友morgan_xww写的这篇文章,果断当个搬运工,嘿嘿。

    康托展开:

    X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0!

    ai为整数,并且0<=ai<i(1<=i<=n)

    应用实例:

    {1,2,3,4,...,n}的排列总共有n!种,将它们从小到大排序,怎样知道其中一种排列是有序序列中的第几个?

    如 {1,2,3} 按从小到大排列一共6个:123 132 213 231 312 321。想知道321是{1,2,3}中第几个大的数。

    这样考虑:第一位是3,小于3的数有1、2 。所以有2*2!个。再看小于第二位,小于2的数只有一个就是1 ,所以有1*1!=1 所以小于32

    的{1,2,3}排列数有2*2!+1*1!=5个。所以321是第6个大的数。2*2!+1*1!是康托展开。

    再举个例子:1324是{1,2,3,4}排列数中第几个大的数:第一位是1小于1的数没有,是0个,0*3!,第二位是3小于3的数有1和2,但1已经在第一位了,所以只有一个数2,1*2! 。第三位是2小于2的数是1,但1在第一位,所以有0个数,0*1!,所以比1324小的排列有0*3!+1*2!+0*1!=2个,1324是第三个大数。

    
    
    int  fac[] = {1,1,2,6,24,120,720,5040,40320}; //i的阶乘为fac[i]
    /*  康托展开.
        {1...n}的全排列由小到大有序,s[]为第几个数  */
    int KT(int n, int s[])
    {
        int i, j, t, sum;
        sum = 0;
        for (i=0; i<n; i++)
        {
            t = 0;
            for (j=i+1; j<n; j++)
                if (s[j] < s[i])
                    t++;
            sum += t*fac[n-i-1];
        }
        return sum+1;
    }
    
    

    康托展开的逆运算:

    {1,2,3,4,5}的全排列已经从小到大排序,要找出第16个数:

    1. 首先用16-1得到15

    2. 用15去除4! 得到0余15

    3. 用15去除3! 得到2余3

    4. 用3去除2! 得到1余1

    5. 用1去除1! 得到1余0

    有0个数比它小的数是1

    所以第一位是1

    有2个数比它小的数是3,但1已经在之前出现过了所以是4

    有1个数比它小的数是2,但1已经在之前出现过了所以是3

    有1个数比它小的数是2,但1,3,4都出现过了所以是5

    最后一个数只能是2

    所以这个数是14352

    /*  康托展开的逆运算.
        {1...n}的全排列,中的第k个数为s[]  */
    void invKT(int n, int k, int s[])
    {
        int i, j, t, vst[8]={0};
        k--;
        for (i=0; i<n; i++)
        {
            t = k/fac[n-i-1];
            for (j=1; j<=n; j++)
                if (!vst[j])
                {
                    if (t == 0) break;
                    t--;
                }
            s[i] = j;
            vst[j] = 1;
            k %= fac[n-i-1];
        }
    }

    本屌实在太弱了,o(╯□╰)o,代码是模仿的%>_<%,当然思路还是理解咯,还学到康托展开这个好东东了,O(∩_∩)O~~,哈哈。

    View Code
      1 /*
      2 ID:spcjv51
      3 PROG:msquare
      4 LANG:C++
      5 */
      6 #include<stdio.h>
      7 #include<string.h>
      8 #include<stdlib.h>
      9 struct que
     10 {
     11     int len;
     12     char ch;
     13     long pre;
     14     int s[8];
     15 } q[50000];
     16 int fac[8]={1,1,2,6,24,120,720,5040};
     17 int hash[50000],goal[8];
     18 int check(struct que *x)
     19 {
     20     int i;
     21     for(i=0; i<8; i++)
     22         if(x->s[i]!=goal[i]) return 0;
     23     return 1;
     24 }
     25 long cotor(struct que *x)
     26 {
     27     long i,j,t,sum;
     28     sum=0;
     29     for(i=0; i<8; i++)
     30     {
     31         t=0;
     32         for(j=i+1; j<8; j++)
     33             if(x->s[j]<x->s[i])
     34                 t++;
     35         sum+=t*fac[7-i];
     36     }
     37     return sum+1;
     38 }
     39 void swap(int *a,int *b)
     40 {
     41     int temp;
     42     temp=*a;
     43     *a=*b;
     44     *b=temp;
     45 }
     46 void print(int k)
     47 {
     48     int i,j,r;
     49     char s[100];
     50     printf("%d\n",q[k].len);
     51     i=0;
     52     while(q[k].len)
     53     {
     54         s[i++]=q[k].ch;
     55         k=q[k].pre;
     56     }
     57     r=0;
     58     for(j=i-1;j>=0;j--)
     59     {
     60         r++;
     61         printf("%c",s[j]);
     62         if(r%60==0) printf("\n");
     63     }
     64     printf("\n");
     65 }
     66 void BFS()
     67 {
     68     long tail,head,i,t;
     69     struct que temp;
     70     hash[cotor(&q[0])]=1;
     71     head=0;
     72     tail=1;
     73     q[0].len=0;
     74     while(head<tail)
     75     {
     76         temp=q[head];
     77         for(i=0; i<4; i++) swap(&temp.s[i],&temp.s[7-i]);
     78         t=cotor(&temp);
     79         if(!hash[t])
     80         {
     81             q[tail]=temp;
     82             q[tail].len=q[head].len+1;
     83             q[tail].ch='A';
     84             q[tail].pre=head;
     85             hash[t]=1;
     86             if(check(&q[tail])) break;
     87             tail++;
     88         }
     89         temp=q[head];
     90         swap(&temp.s[0],&temp.s[3]);
     91         swap(&temp.s[4],&temp.s[7]);
     92         swap(&temp.s[1],&temp.s[3]);
     93         swap(&temp.s[2],&temp.s[3]);
     94         swap(&temp.s[4],&temp.s[6]);
     95         swap(&temp.s[4],&temp.s[5]);
     96         t=cotor(&temp);
     97         if(!hash[t])
     98         {
     99             q[tail]=temp;
    100             q[tail].len=q[head].len+1;
    101             q[tail].ch='B';
    102             q[tail].pre=head;
    103             hash[t]=1;
    104             if(check(&q[tail])) break;
    105             tail++;
    106         }
    107         temp=q[head];
    108         swap(&temp.s[1],&temp.s[2]);
    109         swap(&temp.s[5],&temp.s[6]);
    110         swap(&temp.s[1],&temp.s[5]);
    111         t=cotor(&temp);
    112         if(!hash[t])
    113         {
    114             q[tail]=temp;
    115             q[tail].len=q[head].len+1;
    116             q[tail].ch='C';
    117             q[tail].pre=head;
    118             hash[t]=1;
    119             if(check(&q[tail])) break;
    120             tail++;
    121         }
    122         head++;
    123     }
    124     print(tail);
    125 
    126 }
    127 int main(void)
    128 {
    129     freopen("msquare.in","r",stdin);
    130     freopen("msquare.out","w",stdout);
    131     int i;
    132     for(i=0; i<8; i++)
    133     {
    134         scanf("%d",&goal[i]);
    135         q[0].s[i]=i+1;
    136     }
    137     memset(hash,0,sizeof(hash));
    138     if(check(&q[0]))
    139     printf("0\n\n");
    140     else
    141         BFS();
    142 return 0;
    143 }
     
  • 相关阅读:
    ChineseAlphabetUtil获取汉字首字母工具类
    RandomCodeUtil随机数工具类,随机生成数字、字母、数字字母组合、中文姓名
    ValidateUtil常用验证工具类,如手机、密码、邮箱等
    聊天项目
    日期
    字符串
    java中属性,set get 以及如何学习类的一些用法
    继承 多态 封装
    方法 属性 构造方法和包
    面向对象知识
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/2934358.html
Copyright © 2020-2023  润新知