zoukankan      html  css  js  c++  java
  • 玩具(Toy)

    玩具(Toy)


    Description

    ZC God is best at logical reasoning. One day, he talks about his childhood digital toys.

    The toy is like a Rubik's cube, but not a Rubik's cube. Specifically, it is not a 3 * 3 * 3 structure, but a 4 * 2 structure.

    img

    According to the play of the toy, we can repeatedly transform it in the following three ways:

    A. Exchange the upper and lower lines. For example, the result of the transformation of Figure (a) is shown in Figure (b).

    B. Loop right shift (ZC God knows what this means from an early age). For example, the result of the transformation of Figure (b) is shown in Figure (c).

    C. The center rotates clockwise. For example, the result of the transformation of Figure (c) is shown in Figure (d).

    ZC God is a genius in this respect. He often has a hand that has not dried his nose, the other hand has quickly restored the toy in any state to the initial state shown in Figure (a). In the year when the material was extremely scarce, ZC God had only one such toy; today, the material is extremely rich, and you have many toys in different states. Now, please restore them all.

    Input

    The first line is a positive integer, which is the total number of Rubik's cube toys you have.

    In each one of the following N lines, 8 positive integers, i.e. an arrangement of 1~8, are included, indicating the current state of the toy.

    Here, the representation rule of the cube state is that the first four numbers represent the first line of the cube from left to right, and the last four numbers represent the second line from right to left. For example, the initial state is expressed as "1 2 3 4 5 6 7 8".

    Output

    A total of N lines, each line containing an integer, in turn corresponding to the minimum number of transform needs to be performed to restore each toy.

    In particular, if a toy is not recoverable, the corresponding line outputs -1.

    Example

    Input

    2
    1 2 3 4 5 6 7 8
    8 6 3 5 4 2 7 1
    

    Output

    0
    2
    

    Restrictions

    For 60% of the data, N = 1

    For 100% of the data,1 <= N <= 1,000

    Time: 1 sec

    Memory: 20 MB

    Hints

    State transition diagram and its search

    1. 原理与要点:将它的三种变换反着来一下,利用bfs搜索一下从‘12345678’这个状态通过三种变换可以变成什么状态,并记录下来。由于‘12345678’这种长度为8的字符串不好记录,所以对字符串求一个hash值(康托展开),然后就可以用数组记录可达性。在查询的时候对要查询的字符串求一下hash值,就可以(O(1))的输出查询结果
    2. 遇到的问题:
    3. 时间和空间复杂度: bfs的时间复杂度视可达状态的多少而定,每次查询的复杂度(O(1))。空间复杂度(O(x)),(x = 40320),为8位数字康拓展开的最大值。
    4. 特别或创新:通过bfs搜索并记录,可以做到(O(1))的查询
    #include "iostream"
    #include "cstdio"
    #include "math.h"
    
    using namespace std;
    const int maxn = 40320;
    const int mod = 40900;
    int f[10];
    int dist[maxn];
    const int SZ = 1<<20;  //快速io
    struct fastio{
        char inbuf[SZ];
        char outbuf[SZ];
        fastio(){
            setvbuf(stdin,inbuf,_IOFBF,SZ);
            setvbuf(stdout,outbuf,_IOFBF,SZ);
        }
    }io;
    struct node {
        int a[10], val;
    
        int getcouter() {
            val = 0;
            for (int i = 1, x; i <= 8; i++) {
                x = 0;
                for (int j = i + 1; j <= 8; j++) {
                    if (a[j] < a[i]) {
                        x++;
                    }
                }
                val += x * f[9 - i];
            }
            return val;
        }
    
        void swap(int &x, int &y) {
            int te;
            te = x;
            x = y;
            y = te;
        }
    
        void op1() {
            for (int i = 1; i <= 4; i++) {
                swap(a[i], a[9 - i]);
            }
        }
    
        void op2() {
            a[0] = a[1];
            for (int i = 1; i <= 3; i++) {
                a[i] = a[i + 1];
            }
            a[4] = a[0];
            a[9] = a[8];
            for (int i = 8; i >= 6; i--) {
                a[i] = a[i - 1];
            }
            a[5] = a[9];
        }
    
        void op3() {
            a[0] = a[2];
            a[2] = a[3];
            a[3] = a[6];
            a[6] = a[7];
            a[7] = a[0];
        }
    } que[41000];
    
    void bfs() {
        node now;
        for (int i = 1; i <= 8; i++) {
            now.a[i] = i;
        }
        int from = 0, to = 0;
        dist[now.getcouter()] = 1;
        que[to++] = now;
        node op;
        while (from != to) {
            now = que[from++];
            from %= mod;
            op = now;
            op.op1();
            if (!dist[op.getcouter()]) {
                que[to++] = op;
                to %= mod;
    
                dist[op.getcouter()] = dist[now.val] + 1;
            }
    
            op = now;
            op.op2();
            if (!dist[op.getcouter()]) {
                que[to++] = op;
                to %= mod;
    
                dist[op.getcouter()] = dist[now.val] + 1;
            }
    
            op = now;
            op.op3();
            if (!dist[op.getcouter()]) {
                que[to++] = op;
                to %= mod;
                dist[op.getcouter()] = dist[now.val] + 1;
            }
        }
    
    }
    
    void init() {
        f[1] = 0;
        f[2] = 1;
        for (int i = 3; i <= 8; i++) {
            f[i] = f[i - 1] * (i - 1);
        }
    }
    
    
    int main() {
        init();
        bfs();
        node x;
        int n;
        scanf("%d", &n);
        for (int i = 0; i < n; i++) {
            for (int j = 1; j <= 8; j++) {
                scanf("%d", &x.a[j]);
            }
            printf("%d
    ", dist[x.getcouter()] - 1);
        }
        return 0;
    }
    
    
  • 相关阅读:
    企业命令linux下处理实时日志生成另一个实时日志
    排序算法Java(android)安卓中的list对象排序
    项目设置一个类似HTML map标签功能的Android组件
    最大算法【Manacher模板】HDU 3068——求最长回文子串
    类实现java面向对象上:接口
    线程方法Android:异步调用详解
    输入数字实现分页功能(三层)
    对象主题设计模式读书笔记观察者模式
    网站算法石榴算法严厉打击下 网站盈利方向何在
    闭包执行JavaScript中的闭包
  • 原文地址:https://www.cnblogs.com/albert-biu/p/11542115.html
Copyright © 2011-2022 走看看