MOOC数据结构(下)(自主模式)-玩具(Toy)

2023-10-24 20:30

本文主要是介绍MOOC数据结构(下)(自主模式)-玩具(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.

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

描述

ZC神最擅长逻辑推理,一日,他给大家讲述起自己儿时的数字玩具。

该玩具酷似魔方,又不是魔方。具体来说,它不是一个3 * 3 * 3的结构,而是4 * 2的结构。

按照该玩具约定的玩法,我们可反复地以如下三种方式对其做变换:

A. 交换上下两行。比如,图(a)经此变换后结果如图(b)所示。

B. 循环右移(ZC神从小就懂得这是什么意思的)。比如,图(b)经此变换后结果如图(c)所示。

C. 中心顺时针旋转。比如,图(c)经此变换后结果如图(d)所示。

ZC神自小就是这方面的天才,他往往是一只手还没揩干鼻涕,另一只手已经迅速地将处于任意状态的玩具复原至如图(a)所示的初始状态。物质极其匮乏的当年,ZC神只有一个这样的玩具;物质极大丰富的今天,你已拥有多个处于不同状态的玩具。现在,就请将它们全部复原吧。

输入

第一行是一个正整数,即你拥有的魔方玩具总数N。

接下来共N行,每行8个正整数,是1~8的排列,表示该玩具的当前状态。

这里,魔方状态的表示规则为:前四个数自左向右给出魔方的第一行,后四个数自右向左给出第二行。比如,初始状态表示为“1 2 3 4 5 6 7 8”。

输出

共N行,各含一个整数,依次对应于复原各玩具所需执行变换的最少次数。

特别地,若某个玩具不可复原,则相应行输出-1。

样例

见英文题面

限制

对于60%的数据,N = 1

对于100%的数据,1 <= N <= 1,000

时间:1 sec

空间:20MB

提示

状态转换图及其搜索

 

C++:

/*@Date    : 2018-03-09 13:58:53@Author  : 酸饺子 (changzheng300@foxmail.com)@Link    : https://github.com/SourDumplings@Version : $Id$
*//*
https://dsa.cs.tsinghua.edu.cn/oj/problem.shtml?id=1151
一共有8!=40320中状态,通过哈希表建立映射(康托展开)。
大体思路就是从原始状态开始通过三种操作的反向给出一切可以达到的状态,
通过BFS进行探索。
如果某个状态已经实现过则回溯,因为BFS第一遍到达该结点的步数就是最短路径
故需要记录每个状态的访问标记和需要达到的最小步数,假设步数为-1即为未访问过。
对于逆康托要保存康托的结果,大大提高效率*/#include <iostream>
#include <cstdio>
#include <cstring>using namespace std;static const int MAX = 40321;static const int factorial[8] = {1, 1, 2, 6, 24, 120, 720, 5040};struct stateInfo
{bool valid = false;int A[8];int step = -1;
};static stateInfo data[MAX];struct Queue
{int data[MAX];int front = 0, end = 0;int pop(){int temp = front;front = (front + 1) % MAX;return data[temp];}void push(int i){data[end] = i;end = (end + 1) % MAX;return;}bool empty() { return front == end; }
};template <typename T>
void print(T A[], int n)
{for (int i = 0; i != n; ++i)cout << A[i] << ' ';putchar('\n');return;
}void check_enq(int w, int v, Queue &Q)
{if (data[w].step == -1){data[w].step = data[v].step + 1;Q.push(w);}return;
}int contor(int A[], int n)
{int res = 0;for (int i = 0; i != n; ++i){int smaller = 0;for (int j = i + 1; j != n; ++j){if (A[j] < A[i]) ++smaller;}res += smaller * factorial[n-i-1];}return res;
}void re_contor(int stateNo, int n)
{int temp;bool used[n];memset(used, false, sizeof(used));int tempStateNo = stateNo;for (int i = 0; i != n - 1; ++i){temp = tempStateNo / factorial[n-i-1];int rank = 0;for (int j = 1; j != n + 1; ++j){if (!used[j-1])++rank;if (rank == temp + 1){data[stateNo].A[i] = j;used[j-1] = true;break;}}tempStateNo %= factorial[n-i-1];}for (int i = 0; i != n; ++i){if (!used[i]){data[stateNo].A[n-1] = i + 1;break;}}data[stateNo].valid = true;return;
}void swap(int &a, int &b)
{int temp = a;a = b;b = temp;return;
}// 上下互换
int op1(int A_o[])
{int A[8];memcpy(A, A_o, sizeof(A));swap(A[0], A[7]);swap(A[1], A[6]);swap(A[2], A[5]);swap(A[3], A[4]);int res = contor(A, 8);memcpy(data[res].A, A, sizeof(A));data[res].valid = true;return res;
}// 循环左移
int op2(int A_o[])
{int A[8];memcpy(A, A_o, sizeof(A));int temp1 = A[0], temp2 = A[7];A[0] = A[1];A[1] = A[2];A[2] = A[3];A[7] = A[6];A[6] = A[5];A[5] = A[4];A[3] = temp1;A[4] = temp2;int res = contor(A, 8);memcpy(data[res].A, A, sizeof(A));data[res].valid = true;return res;
}// 逆时针旋转
int op3(int A_o[])
{int A[8];memcpy(A, A_o, sizeof(A));int temp = A[1];A[1] = A[2];A[2] = A[5];A[5] = A[6];A[6] = temp;int res = contor(A, 8);memcpy(data[res].A, A, sizeof(A));data[res].valid = true;return res;
}void BFS()
{Queue Q;Q.push(0);data[0].step = 0;while (!Q.empty()){int v = Q.pop();if (!data[v].valid) re_contor(v, 8);// printf("reached stateNo = %d: ", v);// print(data[v].A, 8);int w1 = op1(data[v].A), w2 = op2(data[v].A), w3 = op3(data[v].A);check_enq(w1, v, Q);check_enq(w2, v, Q);check_enq(w3, v, Q);}return;
}int main(int argc, char const *argv[])
{BFS();int N;scanf("%d", &N);for (int i = 0; i != N; ++i){int A[8];for (int j = 0; j != 8; ++j) scanf("%d", &A[j]);int stateNo = contor(A, 8);// printf("stateNo = %d for A: \n", stateNo);// print(A, 8);printf("%d\n", data[stateNo].step);}return 0;
}

 

这篇关于MOOC数据结构(下)(自主模式)-玩具(Toy)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/277601

相关文章

Go语言中三种容器类型的数据结构详解

《Go语言中三种容器类型的数据结构详解》在Go语言中,有三种主要的容器类型用于存储和操作集合数据:本文主要介绍三者的使用与区别,感兴趣的小伙伴可以跟随小编一起学习一下... 目录基本概念1. 数组(Array)2. 切片(Slice)3. 映射(Map)对比总结注意事项基本概念在 Go 语言中,有三种主要

Java实现状态模式的示例代码

《Java实现状态模式的示例代码》状态模式是一种行为型设计模式,允许对象根据其内部状态改变行为,本文主要介绍了Java实现状态模式的示例代码,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来... 目录一、简介1、定义2、状态模式的结构二、Java实现案例1、电灯开关状态案例2、番茄工作法状态案例

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

《数据结构(C语言版)第二版》第八章-排序(8.3-交换排序、8.4-选择排序)

8.3 交换排序 8.3.1 冒泡排序 【算法特点】 (1) 稳定排序。 (2) 可用于链式存储结构。 (3) 移动记录次数较多,算法平均时间性能比直接插入排序差。当初始记录无序,n较大时, 此算法不宜采用。 #include <stdio.h>#include <stdlib.h>#define MAXSIZE 26typedef int KeyType;typedef char In

模版方法模式template method

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/template-method 超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。 上层接口有默认实现的方法和子类需要自己实现的方法

【iOS】MVC模式

MVC模式 MVC模式MVC模式demo MVC模式 MVC模式全称为model(模型)view(视图)controller(控制器),他分为三个不同的层分别负责不同的职责。 View:该层用于存放视图,该层中我们可以对页面及控件进行布局。Model:模型一般都拥有很好的可复用性,在该层中,我们可以统一管理一些数据。Controlller:该层充当一个CPU的功能,即该应用程序

迭代器模式iterator

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/iterator 不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素

《x86汇编语言:从实模式到保护模式》视频来了

《x86汇编语言:从实模式到保护模式》视频来了 很多朋友留言,说我的专栏《x86汇编语言:从实模式到保护模式》写得很详细,还有的朋友希望我能写得更细,最好是覆盖全书的所有章节。 毕竟我不是作者,只有作者的解读才是最权威的。 当初我学习这本书的时候,只能靠自己摸索,网上搜不到什么好资源。 如果你正在学这本书或者汇编语言,那你有福气了。 本书作者李忠老师,以此书为蓝本,录制了全套视频。 试