玩具(玩具)
清华OJ——数据结构与算法实验(中国石油大学)
玩具(Toy)
Description
区中心局(Zone Center)上帝最擅长逻辑推理。一天,他谈到了他童年的数码玩具。
玩具像魔方,但不是魔方。具体来说,它不是3 * 3 * 3结构,而是4 * 2结构。
根据玩具的玩法,我们可以通过以下三种方式反复变换3360
A.交换上下线。例如,图(a)的转换结果如图(b)所示。
B.循环右移(ZC从小就知道这意味着什么)。例如,图(b)的转换结果如图(c)所示。
C.中心顺时针旋转。例如,图(c)的转换结果如图(d)所示。
区中心局(Zone Center)上帝在这方面是个天才。他经常有一只手没有擦干鼻子,另一只手已经迅速将玩具在任何状态下恢复到图(a)所示的初始状态。在材料极度匮乏的那一年,ZC神只有一个这样的玩具;如今,材料极其丰富,你在不同的州有许多玩具。现在,请全部恢复。
Input
第一行是正整数,是你拥有的魔方玩具总数。
在以下普通行中的每一行中,包含8个正整数,即1~8的排列,表示玩具的当前状态。
这里,立方体状态的表示规则是,前四个数字从左到右表示立方体的第一行,后四个数字从右到左表示第二行。例如,初始状态表示为"1 2 3 4 5 6 7 8"。
Output
总共普通行,每一行包含一个整数,依次对应需要执行的最小变换次数来还原每个玩具。
特别是,如果玩具不可回收,相应的线路输出-1。
Example
投入
2
1 2 3 4 5 6 7 8
8 6 3 5 4 2 7 1
输出
0
2
Restrictions
60%的
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
提示
状态转换图及其搜索
1 #includecstdio
2 #includeiostream
3 #includecstring
4 using namespace std;
5
6 int fac[]= {1, 1, 2, 6, 24, 120, 720, 5040, 40320}; //阶乘
7
8 int f(int x)
9 {
10 int a[9],k=0;
11 while(x)
12 {
13 a[k++]=x%10;
14 x/=10;
15 }
16 // for(int i=0;ik;i++)printf("%d",a[i]);
17 // printf("\n");
18 int ans=0,tmp;
19 for(int i=0; ik; i++)
20 {
21 tmp=0;//记录有几个比它小的数
22 for(int j=i+1; jk; j++)
23 {
24 if(a[j]a[i])tmp++;
25 }
26 ans+=tmp*fac[k-i-1];
27 }
28 return ans;
29 }
30
31 int dis[45050]={0};
32 int q[45050],c1=0,c2=0;
33 int getnum(char a[])
34 {
35 int ans=0;
36 for(int i=0;i8;i++)
37 {
38 ans*=10;
39 ans+=a[i]-'0';
40 }
41 return ans;
42 }
43
44 void bfs()
45 {
46 c1=0;
47 c2=1;
48 q[0]=12345678;
49 dis[f(12345678)]=0;
50
51 while(c1!=c2)
52 {
53 int now=q[c1++];
54
55
56 int next;
57 char a[10],b[10];
58 sprintf(a,"%d",now);
59 now=f(now);
60
61 for(int i=7;i=0;i--)b[i]=a[7-i];
62
63 next=getnum(b);
64 //printf("aaaa");
65 int id=f(next);
66 if(dis[id]==-1)
67 {
68 dis[id]=dis[now]+1;
69 q[c2++]=next;
70 }
71 //58763214 a
72 //87654321 b
73 b[0]=a[1];
74 b[1]=a[2];
75 b[2]=a[3];
76 b[3]=a[0];
77 b[4]=a[7];
78 b[5]=a[4];
79 b[6]=a[5];
80 b[7]=a[6];
81 next=getnum(b);
82 id=f(next);
83 if(dis[id]==-1)
84 {
85 dis[id]=dis[now]+1;
86 q[c2++]=next;
87 }
88
89 //51863724 a
90 //58763214 b
91 b[0]=a[0];
92 b[1]=a[2];
93 b[2]=a[5];
94 b[3]=a[3];
95 b[4]=a[4];
96 b[5]=a[6];
97 b[6]=a[1];
98 b[7]=a[7];
99 next=getnum(b);
100 id=f(next);
101 if(dis[id]==-1)
102 {
103 dis[id]=dis[now]+1;
104 q[c2++]=next;
105 }
106 }
107 }
108
109
110 int main()
111 {
112 memset(dis,-1,sizeof(dis));
113 bfs();
114
115 int n;
116 scanf("%d",n);
117 while(n--)
118 {
119 int now=0;
120 for(int i=0;i8;i++)
121 {
122 int a;
123 scanf("%d",a);
124 now*=10;
125 now+=a;
126 }
127
128 printf("%d\n",dis[f(now)]);
129 }
130 return 0;
131 }
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/121788.html
