• 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 }
  • 相关阅读:
    Hive join操作优化
    php中 date 函数中的格式参数
    Mysql分表之后的聚合统计
    使用Elasticsearch-Dump工具复制ES库
    Json Path 语法详解(Java)
    Json Path 语法
    关于qt5.2~qt5.8的下载地址
    RTL8812AU双频无线网卡在ubuntu19和20上的驱动安装
    使用vscode对threejs的本地调试
    ThreeJS中创建文字的几种方法
  • 原文地址:https://www.cnblogs.com/stranger-/p/10080206.html
Copyright © 2020-2023  润新知