hdu 1430 (BFS 康托展开 或 map )

第一眼看到这题就直接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 }
时间: 2024-08-02 06:55:27

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

hdu 5012 bfs 康托展开

Dice Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 491    Accepted Submission(s): 290 Problem Description There are 2 special dices on the table. On each face of the dice, a distinct number w

poj 1077 八数码(BFS+康托展开)

1 /* 2 题意:八数码问题,给出3*3的矩阵含1~8以及x,给出一个符合的解使得移动后的矩阵的顺序为1~8,最后为x 3 4 题解:BFS 5 需要用到康托展开来表示状态,不然数组无法完全表示所有状态,这样BFS就无法判断找不到解的情况(status 6 的0ms,0KB究竟是怎么做到的,简直不能想象=.=) 7 */ 8 #include <cstdio> 9 #include <cstring> 10 #include <queue> 11 #include &

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

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2170    Accepted Submission(s): 455 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜

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

http://acm.hdu.edu.cn/showproblem.php?pid=1043 题意:给出一个八数码,求出到达指定状态的路径. 思路:路径寻找问题.在这道题里用到的知识点挺多的.第一次用双向BFS来做. ①双向BFS 在单向BFS的基础上,多建一个从终止状态开始搜索的队列,当然这个时候需要两个vis[]辅助数组,分别记录两个队列的访问情况,当两个队列相遇时即可终止循环. ②康托展开 X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[

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

Eight Descriptions: 简单介绍一下八数码问题:在一个3×3的九宫格上,填有1~8八个数字,空余一个位置,例如下图: 1 2 3 4 5 6 7 8   在上图中,由于右下角位置是空的,你可以移动数字,比如可以将数字6下移一位: 1 2 3   1 2 3 4 5 6 → 4 5   7 8     7 8 6 或者将数字8右移一位: 1 2 3   1 2 3 4 5 6 → 4 5 6 7 8     7   8 1~8按顺序排列的情况称为"初始状态"(如最上方图)

hdu 1043 Eight(康托展开,打表)

1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef long long LL; 5 6 /** 7 学习:(1)康托展开的使用 8 (2)路径记录 9 ? A* 10 ? 双向bfs 11 */ 12 13 int t[9],s[9]; 14 bool vis[362880 + 10]; 15 char ans[362880 + 10][42]; 16 int fac[]={1,1

POJ 1077 Eight(bfs+康托展开)

Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 41040   Accepted: 16901   Special Judge Description The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've seen it. It is constructed with 15

hdu 5012 bfs --- 慎用STL 比如MAP判重

http://acm.hdu.edu.cn/showproblem.php?pid=5012 发现一个问题 如果Sting s = '1'+'2'+'3'; s!="123"!!!!!!  而是有乱码 先贴一份自己的TLE 代码, 超时应该是因为: 1.cin 2.map判重 map find太花时间 3.string花时间 4.其实不用两个都旋转,只要旋转一个就行,这样可以省下很多时间 包括少用了make_pair pair的判重等等....哎  二笔了  太暴力了 #include

BFS+康托展开(洛谷1379 八数码难题)

在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变. 输入格式: 输入初试状态,一行九个数字,空格用0表示 输出格式: 只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据) 输入样例#1: 2831