第一眼看到这题就直接BFS爆搜,第一发爆了内存,傻逼了忘标记了,然后就改,咋标记呢。

然后想到用map函数,就8!个不同的排列,换成字符串用map标记。然后又交一发果断超时,伤心,最恨超时,还不如来个wa算了。

然后卡着了,后来上网上搜,要用康托展开,康托展开是什么鬼?然后学习了一下,就是个映射,感觉和map差不多。

http://blog.csdn.net/zhongkeli/article/details/6966805这个学习一下康托展开。

其实本题的关键不是康托展开,而是置换。

以12345678为起始状态开始搜它经过3种变换能到达的所有状态的最小步数,每搜到一个记录下来,可以用康托展开,也可以用C++ STL库里的map

所以只要搜一次就够了,然后记录。那么咋转置呢。举个列子 初态为65871234 目标态为87125463,那么初态和12345678比较,6和1对应,5和2对应

8和3对应......,所以目标态的8为初态的第三位,而初态的第三位对应12345678中的三,所以目标态第一位转为3,同理第2位转为4......

最后的到状态为34562817,所以只要知道12345678转为34562817的最小步数就为所求。

下面给两段代码一个是用map写的一个是用康托展开写的。map写的运行时间比较慢200多Ms,不过时间足够,题目好像是给了5s吧,

康托展开是46ms.

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1430;

  1 #include<stdio.h>
2 #include<algorithm>
3 #include<iostream>
4 #include<string.h>
5 #include<stdlib.h>
6 #include<math.h>
7 #include<queue>
8 #include<stack>
9 #include<cstdio>
10 #include<map>
11 void bfs();
12 using namespace std;
13 void AA(char *p,char *q);
14 void BB(char *p,char *q);
15 void CC(char *p,char *q);
16 int N=50005;
17 map<string,int>my;
18 char t[10]="12345678";
19 char a[41000][100];//总共有8!的状态每个状态对应一个数然后用数组存变换的步奏
20 typedef struct pp
21 {
22
23 char ab[10];
24 int n;
25
26 } ss;//开结构体存步数。
27 int main(void)
28 {
29
30 int n,i,j,k,p,q;
31 char aa[10];
32 char bb[10];
33 char cc[10];
34 bfs();
35 while(scanf("%s %s",aa,bb)!=EOF)
36 {
37 int yu=0;
38 for(i=0; i<8; i++)
39 {
40 for(j=0; j<8; j++)
41 {
42 if(bb[i]==aa[j])
43 {
44 cc[yu++]=j+1+'0';
45 }
46 }
47 }
48 cc[8]='\0';
49 int sh=my[cc];
50 puts(a[sh]);
51 }
52 return 0;
53
54 }
55 void bfs()
56 {
57 int i,j,k,p,q,l;
58 ss ll,mm;
59 ll.n=1;
60 int v=1;
61 my[t]=v;//map标记并映射为一个数
62 v++;
63 strcpy(ll.ab,t);
64 queue<ss>que;
65 que.push(ll);
66 while(!que.empty())
67 {
68 mm=que.front();
69 que.pop();
70 ss pp;
71 AA(pp.ab,mm.ab);
72
73 if(my[pp.ab]==0)
74 {
75 my[pp.ab]=v;
76 strcpy(a[v],a[mm.n]);//接上一个所有的变化步数
77 l=strlen(a[v]);//最后加上本次的变换
78 a[v][l]='A';
79 pp.n=v;
80 v++;
81 que.push(pp);
82 }
83 BB(pp.ab,mm.ab);
84
85 if(my[pp.ab]==0)
86 {
87 my[pp.ab]=v;
88 strcpy(a[v],a[mm.n]);
89 l=strlen(a[v]);
90 a[v][l]='B';
91
92 pp.n=v;
93 v++;
94 que.push(pp);
95 }
96 CC(pp.ab,mm.ab);
97
98 if(my[pp.ab]==0)
99 {
100 my[pp.ab]=v;
101 strcpy(a[v],a[mm.n]);
102 l=strlen(a[v]);
103 a[v][l]='C';
104 pp.n=v;
105 v++;
106 que.push(pp);
107 }
108
109
110
111
112 }
113
114
115
116
117
118
119 }//三种不同的转换;
120 void AA(char *p,char *q)
121 {
122 int i,j,k;
123 p[0]=q[7];
124 p[1]=q[6];
125 p[2]=q[5];
126 p[3]=q[4];
127 p[4]=q[3];
128 p[5]=q[2];
129 p[6]=q[1];
130 p[7]=q[0];
131 p[8]='\0';
132 }
133
134 void BB(char *p,char *q)
135 {
136 int i,j,k;
137 p[0]=q[3];
138 p[1]=q[0];
139 p[2]=q[1];
140 p[3]=q[2];
141 p[4]=q[5];
142 p[5]=q[6];
143 p[6]=q[7];
144 p[7]=q[4];
145 p[8]='\0';
146 }
147
148 void CC(char *p,char *q)
149 {
150 p[0]=q[0];
151 p[1]=q[6];
152 p[2]=q[1];
153 p[3]=q[3];
154 p[4]=q[4];
155 p[5]=q[2];
156 p[6]=q[5];
157 p[7]=q[7];
158 p[8]='\0';
159 }
  1 #include<stdio.h>
2 #include<algorithm>
3 #include<iostream>
4 #include<string.h>
5 #include<stdlib.h>
6 #include<math.h>
7 #include<queue>
8 #include<stack>
9 #include<cstdio>
10 int kt(char *p);
11 void bfs();
12 using namespace std;
13 void AA(char *p,char *q);
14 void BB(char *p,char *q);
15 void CC(char *p,char *q);
16 int as[10];
17 int N=50005;
18 bool vis[50005];
19 char t[10]="12345678";
20 char a[41000][100];
21 typedef struct pp
22 {
23 char ab[10];
24 int n;
25
26 } ss;
27 int main(void)
28 {
29 as[0]=1;
30 as[1]=1;
31 as[2]=2;
32 as[3]=6;
33 as[4]=24;
34 as[5]=120;
35 as[6]=720;
36 as[7]=5040;//康托展开预处理
37 int n,i,j,k,p,q;
38 char aa[10];
39 char bb[10];
40 char cc[10];
41 memset(vis,0,sizeof(vis));
42 bfs();
43 while(scanf("%s %s",aa,bb)!=EOF)
44 {
45 int yu=0;
46 for(i=0; i<8; i++)
47 {
48 for(j=0; j<8; j++)
49 {
50 if(bb[i]==aa[j])
51 {
52 cc[yu++]=j+1+'0';
53 }
54 }
55 }
56
57 int sh=kt(cc);
58
59 puts(a[sh]);
60 }
61
62 return 0;
63
64 }
65
66 int kt(char *p)//康托展开
67 {
68 int i,j;
69 int kk=0;
70 for(i=0; i<8; i++)
71 {
72 int yy=0;
73 for(j=i+1; j<8; j++)
74 {
75 if((p[i]-'0')>(p[j]-'0'))
76 {
77 yy++;
78 }
79 }
80 kk+=yy*as[7-i];
81
82
83 }
84 return kk;
85 }
86
87 void bfs()
88 {
89 int i,j,k,p,q,l;
90 ss ll,mm;
91 ll.n=0;
92 vis[0]=true;
93 strcpy(ll.ab,t);
94 queue<ss>que;
95 que.push(ll);
96 while(!que.empty())
97 {
98 mm=que.front();
99 que.pop();
100 ss pp;
101 AA(pp.ab,mm.ab);
102 int yy=kt(pp.ab);
103 if(!vis[yy])
104 {
105 vis[yy]=true;
106 strcpy(a[yy],a[mm.n]);
107 l=strlen(a[yy]);
108 a[yy][l]='A';
109 pp.n=yy;
110 que.push(pp);
111 }
112 BB(pp.ab,mm.ab);
113 yy=kt(pp.ab);
114 if(!vis[yy])
115 {
116 vis[yy]=true;
117 strcpy(a[yy],a[mm.n]);
118 l=strlen(a[yy]);
119 a[yy][l]='B';
120 pp.n=yy;
121 que.push(pp);
122 }
123 CC(pp.ab,mm.ab);
124 yy=kt(pp.ab);
125 if(!vis[yy])
126 {
127 vis[yy]=true;
128 strcpy(a[yy],a[mm.n]);
129 l=strlen(a[yy]);
130 a[yy][l]='C';
131 pp.n=yy;
132 que.push(pp);
133 }
134
135
136
137
138 }
139
140
141
142
143
144 }
145 void AA(char *p,char *q)
146 {
147 int i,j,k;
148 p[0]=q[7];
149 p[1]=q[6];
150 p[2]=q[5];
151 p[3]=q[4];
152 p[4]=q[3];
153 p[5]=q[2];
154 p[6]=q[1];
155 p[7]=q[0];
156 }
157
158 void BB(char *p,char *q)
159 {
160 int i,j,k;
161 p[0]=q[3];
162 p[1]=q[0];
163 p[2]=q[1];
164 p[3]=q[2];
165 p[4]=q[5];
166 p[5]=q[6];
167 p[6]=q[7];
168 p[7]=q[4];
169 }
170
171 void CC(char *p,char *q)
172 {
173 p[0]=q[0];
174 p[1]=q[6];
175 p[2]=q[1];
176 p[3]=q[3];
177 p[4]=q[4];
178 p[5]=q[2];
179 p[6]=q[5];
180 p[7]=q[7];
181 }

hdu 1430 (BFS 康托展开 或 map )的更多相关文章

  1. hdu 1430(BFS+康托展开+映射+输出路径)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  2. hdu 5012 bfs 康托展开

    Dice Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submi ...

  3. HDU_1043 Eight 【逆向BFS + 康托展开 】【A* + 康托展开 】

    一.题目 http://acm.hdu.edu.cn/showproblem.php?pid=1043 二.两种方法 该题很明显,是一个八数码的问题,就是9宫格,里面有一个空格,外加1~8的数字,任意 ...

  4. HDU - 1430 魔板 【BFS + 康托展开 + 哈希】

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1430 思路 我刚开始 想到的 就是 康托展开 但是这个题目是 多组输入 即使用 康托展开 也是会T的 ...

  5. hdu.1430.魔板(bfs + 康托展开)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  6. HDU 1043 Eight(双向BFS+康托展开)

    http://acm.hdu.edu.cn/showproblem.php?pid=1043 题意:给出一个八数码,求出到达指定状态的路径. 思路:路径寻找问题.在这道题里用到的知识点挺多的.第一次用 ...

  7. 【HDU - 1043】Eight(反向bfs+康托展开)

    Eight Descriptions: 简单介绍一下八数码问题:在一个3×3的九宫格上,填有1~8八个数字,空余一个位置,例如下图: 1 2 3 4 5 6 7 8   在上图中,由于右下角位置是空的 ...

  8. POJ 1077 && HDU 1043 Eight A*算法,bfs,康托展开,hash 难度:3

    http://poj.org/problem?id=1077 http://acm.hdu.edu.cn/showproblem.php?pid=1043 X=a[n]*(n-1)!+a[n-1]*( ...

  9. POJ 1077 Eight (BFS+康托展开)详解

    本题知识点和基本代码来自<算法竞赛 入门到进阶>(作者:罗勇军 郭卫斌) 如有问题欢迎巨巨们提出 题意:八数码问题是在一个3*3的棋盘上放置编号为1~8的方块,其中有一块为控制,与空格相邻 ...

随机推荐

  1. CMSIS-RTOS 信号量Semaphores

    信号量Semaphores 和信号类似,信号量也是一种同步多个线程的方式,简单来讲,信号量就是装有一些令牌的容器.当一个线程在执行过程中,就可能遇到一个系统调用来获取信号量令牌,如果这个信号量包含多个 ...

  2. 关于SQL中Union和Join的用法

    转自帘卷西风的专栏(http://blog.csdn.net/ljxfblog) https://blog.csdn.net/ljxfblog/article/details/52066006 Uni ...

  3. Python os模块与sys模块

    1.os模块简单使用及说明 # -*- coding:utf-8 -*- """ os模块主要用于系统,处理程序与系统交互问题 大部分如属性等功能在linux系统中会使用 ...

  4. 取gridview中textbox的值【C#】

    <asp:GridView ID="gridView" runat="server" OnRowCommand="gridView_RowCom ...

  5. LeetCode移除元素

    LeetCode 移除元素 题目描述 给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度. 不需要使用额外的数组空间,你必须仅使用 O(1) ...

  6. 【leetcode】121. Best Time to Buy and Sell Stock(股票问题)

    You are given an array prices where prices[i] is the price of a given stock on the ith day. You want ...

  7. 容器的分类与各种测试(二)——vector部分用法

    向量 vector 是一种对象实体, 能够容纳许多其他类型相同的元素, 因此又被称为容器. 与string相同, vector 同属于STL(Standard Template Library, 标准 ...

  8. Shell变量与算术运算

    区分两个 Shell Shell 语言与 Shell 解释器 Shell 语言 写 Shell 脚本使用的是 Shell 语言,Shell 既是一种命令语言,又是一种程序设计语言. 作为命令语言,它交 ...

  9. 01 nodejs MVC gulp 项目搭建

    文本内容 使用generator-express创建nodejs MVC DEMO 使用gulp实时编译项目 npm安装二进制包,无须再编译wget https://nodejs.org/dist/v ...

  10. linux系统下命令的学习

    本博客是本人工作时做的笔记 ps aux |grep ^profile |grep A190200024 ^ 表示行首匹配 linux查看文件大小: 具体可查看:https://www.cnblogs ...