2016 ACM/ICPC 区域赛(北京) E 题 bfs

https://vjudge.net/problem/UVALive-7672

题意    输入一个五位数n 问由12345变到n的操作最少次数 不可达输出-1

有三种操作

1.交换相邻的位置 次数不限制

2.使某一位上的数字+1   最多使用三次 (mod 10)

3.使某一位上的数字*2   最多使用两次    (mod 10)

解析 很容易想到预处理,然后O(1) 查询,操作次数最少,所以就bfs,一层一层向外拓展。

需要注意的是 一个数被访问过还可以再被访问(进队列),因为得到一个数可以有不同的操作方案,我们都需要将它向下进行扩展

比如说 26345 

可   以    12345->22345(1+1)->23345->26345 (两次2操作,一次3操作)

还可以    12345->22345(1 * 2)->23345->26345 (一次2操作,两次3操作)

两个状态都要进队列才能满足答案正确性。然后开个三维数组记录vis[26345][2][1]标记这个状态访问过了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int inf=0x3f3f3f3f;
 4 int ans[100000][1];
 5 int vis[100000][4][3]; //0 swap,1 +,2 double
 6 struct node
 7 {
 8     string s;
 9     int a,b,c;
10 };
11 int change(string s)//string 转int
12 {
13     int x=1,ans=0;
14     for(int i=s.length()-1;i>=0;i--)
15     {
16         ans+=(int)(s[i]-'0')*x;
17         x*=10;
18     }
19     return ans;
20 }
21 void bfs()
22 {
23     memset(ans,inf,sizeof(ans));
24     memset(vis,0,sizeof(vis));
25     queue<node>q;
26     string beg="12345";
27     q.push({beg,0,0,0});
28     ans[change(beg)][0]=0;
29     while(!q.empty())
30     {
31         node e=q.front();
32         string now=e.s;q.pop();
33         int noww=change(now);
34         if(e.b<3)
35         {
36             for(int i=0;i<5;i++)
37             {
38                 string t=now;
39                 if(t[i]=='9') t[i]='0';
40                 else t[i]++;
41                 int temp=change(t);
42                 if(!vis[temp][e.b+1][e.c])
43                 {
44                     vis[temp][e.b+1][e.c]=1;
45                     ans[temp][0]=min(ans[temp][0],e.a+e.b+e.c+1);
46                     q.push({t,e.a,e.b+1,e.c});
47                 }
48             }
49         }
50         if(e.c<2)
51         {
52             for(int i=0;i<5;i++)
53             {
54                 string t=now;
55                 int k=t[i]-'0';
56                 k+=k,k%=10;
57                 t[i]='0'+k;
58                 int temp=change(t);
59                 if(!vis[temp][e.b][e.c+1])
60                 {
61                     vis[temp][e.b][e.c+1]=1;
62                     ans[temp][0]=min(ans[temp][0],e.a+e.b+e.c+1);
63                     q.push({t,e.a,e.b,e.c+1});
64                 }
65             }
66         }
67         for(int i=0;i<4;i++)
68         {
69             string t=now;
70             swap(t[i],t[i+1]);
71             int temp=change(t);
72             if(ans[temp][0]==inf)
73             {
74                 ans[temp][0]=min(ans[temp][0],e.a+e.b+e.c+1);
75                 q.push({t,e.a+1,e.b,e.c});
76             }
77         }
78     }
79 }
80 int main()
81 {
82     bfs();
83     string s;
84     while(cin>>s)
85     {
86         int x=change(s);
87         if(ans[x][0]==inf)
88             cout<<-1<<endl;
89         else
90             cout<<ans[x][0]<<endl;
91     }
92 }
原文地址:https://www.cnblogs.com/stranger-/p/10080206.html