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 }

 

转载于:https://www.cnblogs.com/zzuli2sjy/p/4924089.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值