• 第十场 hdu 6171 Admiral(双向bfs找交点)


    http://acm.hdu.edu.cn/showproblem.php?pid=6171

    题目大意:给你一个塔形的数据共有1个0、2个1、3个2、4个3、5个4、6个5.你能够把0这个数据和它的上、左上、下、右下的数据进行交换。问在最多20步内能否变成按顺序排列的塔形数据?如果能输出最小步数,否则输出-1.

    解题思路:因为有20步4个方向所以暴力搜索肯定是不可以的。因为有起点有终点所以我们能分两部分去搜索。但是这样搜索的话还是要去找枚举相遇的,这样的话还是会超时的,所以我们在搜索的同时还要找出来一下相遇的最少步数。
    我们应该用队列去完成宽搜并用map去存储到达该状态的最少步数,并且起点和终点状态最多只能向前枚举10次以减少时间复杂度。如果在某个状态枚举的情况相遇了则说明已经找到了最少的步数。
    我们应该对给出的状态是不是起点状态进行特判,找到最少步数为0的情况。

    AC代码:

      1 #include <iostream>
      2 #include<bits/stdc++.h>
      3 //if(~i)//当i不是-1时满足条件
      4 using namespace std;
      5 queue<string>que;
      6 map<string,int>mp;
      7 int up[]= {-1,0,-1,1,2,-1,3,4,5,-1,6,7,8,9,-1,10,11,12,13,14,-1};
      8 int upleft[]= {-1,-1,0,-1,1,2,-1,3,4,5,-1,6,7,8,9,-1,10,11,12,13,14};
      9 int down[]= {1,3,4,6,7,8,10,11,12,13,15,16,17,18,19,-1,-1,-1,-1,-1,-1};
     10 int downright[]= {2,4,5,7,8,9,11,12,13,14,16,17,18,19,20,-1,-1,-1,-1,-1,-1};
     11 string ori="011222333344444555555";
     12 
     13 int solve(string next,string now,int nextpos,int pos)
     14 {
     15     if(~nextpos)
     16     {
     17         swap(next[pos],next[nextpos]);
     18         next[21]=nextpos/10+'0';
     19         next[22]=nextpos%10+'0';
     20         int cnt1=mp[next];
     21         int cnt2=mp[now];
     22         if(!cnt1)
     23         {
     24             mp[next]=mp[now]+1;
     25             que.push(next);
     26         }
     27         else if((cnt1>=20&&cnt2<=11)||(cnt2>=20&&cnt1<=11))
     28          return cnt1+cnt2-20;
     29         swap(next[pos],next[nextpos]);
     30     }
     31     return 0;
     32 }
     33 int dfs(string s)
     34 {
     35     int index;
     36     while(!que.empty())
     37         que.pop();
     38     mp.clear();
     39     for(int i=0; i<21; i++)
     40     {
     41         if(s[i]=='0')
     42         {
     43             index=i;
     44             break;
     45         }
     46     }
     47     char st[5];
     48     st[0]=index/10+'0';
     49     st[1]=index%10+'0';
     50     st[2]='';
     51     que.push(s+st);
     52     que.push(ori+"00");
     53     mp[s+st]=20;
     54     mp[ori+"00"]=1;
     55     while(!que.empty())
     56     {
     57         string now=que.front();
     58         que.pop();
     59         int num=mp[now];
     60         if(num==11||num==30)
     61             continue;
     62         int pos=(now[21]-'0')*10+(now[22]-'0');
     63         int nextpos=up[pos];
     64         string next=now;
     65         int ans=solve(next,now,nextpos,pos);
     66         if(ans)
     67             return ans;
     68         nextpos=upleft[pos];
     69         ans=solve(next,now,nextpos,pos);
     70         if(ans)
     71             return ans;
     72         nextpos=down[pos];
     73         ans=solve(next,now,nextpos,pos);
     74         if(ans)
     75             return ans;
     76         nextpos=downright[pos];
     77         ans=solve(next,now,nextpos,pos);
     78         if(ans)
     79             return ans;
     80     }
     81     return -1;
     82 }
     83 int main()
     84 {
     85     int t;
     86     //freopen("1001.in","r",stdin);
     87     scanf("%d",&t);
     88     while(t--)
     89     {
     90         string s="",st;
     91         for(int i=0; i<21; i++)
     92         {
     93             cin>>st;
     94             s+=st;
     95         }
     96         if(s==ori)
     97         {
     98             printf("0
    ");
     99             continue;
    100         }
    101         int ans=dfs(s);
    102         if(ans==-1)
    103         printf("too difficult
    ");
    104         else
    105         printf("%d
    ",ans);
    106     }
    107     return 0;
    108 }
    View Code
  • 相关阅读:
    CSS实现雨滴动画效果
    大型网站架构系列:电商网站架构案例
    CSS 不定宽高的垂直水平居中方式总汇
    js中尺寸类样式
    Tiling
    排序二叉树
    算术表达式的转换
    Area
    catch that cow
    R中双表操作学习[转载]
  • 原文地址:https://www.cnblogs.com/wang-ya-wei/p/7436154.html
Copyright © 2020-2023  润新知