閱讀991 返回首頁    go 阿裏雲 go 技術社區[雲棲]


hdu 1067 Gap

  

    本來認為是個數學題或者dp題,但是後來看到規則發現用搜索完全可以做

    因為規則限製,每次隻能把空白左邊下一位的數移動到空白處,所以每次最多走4種情況,這就可以bfs了

    一開始用map的,但是TLE了(雖然不是這個問題)於是手寫hash,對999991取了個餘,雖然一定不完善,但是數據沒那麼強。

    手寫hash後依舊TLE……最後檢查了好幾遍才發現是空格左邊可能仍是空格,這一點沒有考慮到,所以一直TLE(差點手寫隊列了o(╯□╰)o)

    加了個判斷後,500ms就過了……

 

    注意位運算的優先級,今天被坑好幾次了

 

/*
author:jxy
lang:C/C++
university:China,Xidian University
**If you need to reprint,please indicate the source**
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <map>
#define INF 1E9
using namespace std;
const char ss[32]={11,12,13,14,15,16,17,0,21,22,23,24,25,26,27,0,31,32,33,34,35,36,37,0,41,42,43,44,45,46,47,0};
string aim="";
struct node
{
    int x,y;
};
char m[4][8];
struct state
{
   node pos[50],blank[4];//pos確定每個數字位置,blank是4個空格位置
   string s;//圖
   int lvl;//步數
};
string m2s()//把圖變成字符串
{
    string now="";
    int i,j;
    for(i=0;i<4;i++)
     for(j=0;j<8;j++)
      now.push_back(m[i][j]);
    return now;
}
int get_hash(string s)//獲得hash值
{
    long long ans=0;
    for(int i=0;i<32;i++)
        ans=(ans<<1)+s[i];
    return ans%999991;
}
bool vis[1000000];
queue<state> q;
state now,next;
node temp;
int bfs()
{
    memset(vis,0,sizeof(vis));
    while(!q.empty())q.pop();
    int i,j,t=0,k,o,lvl;
    for(i=0;i<4;i++)
     for(j=0;j<8;j++)
     {
         temp.x=i;temp.y=j;
         if(m[i][j]==0)now.blank[t++]=temp;
         else now.pos[m[i][j]]=temp;
     }
    now.s=m2s();vis[get_hash(now.s)]=1;
    now.lvl=1;
    q.push(now);
    int Aim=get_hash(aim);
    while(!q.empty()&&!vis[Aim])
    {
        now=q.front();q.pop();
        next=now;
        next.lvl=now.lvl+1;
        for(i=0;i<4;i++)
        {
            node &b=next.blank[i];
            o=8*b.x+b.y-1;
            t=next.s[o];
            if(t%10==7||t==0)continue;//注意空格旁還是空格的情況
            k=t+1;
            node &p=next.pos[k];
            k=p.x*8+p.y;
            o++;
            swap(next.s[o],next.s[k]);//移動位置
            t=get_hash(next.s);
            if(!vis[t])
            {
                if(t==Aim)return next.lvl-1;
                swap(p,b);
                q.push(next);
                vis[t]=1;
                swap(p,b);
            }
            swap(next.s[o],next.s[k]);//恢複
        }
    }
    return vis[Aim]-1;
}
int main()
{
   int T;
   for(T=0;T<32;T++)aim.push_back(ss[T]);
   scanf("%d",&T);
   while(T--)
   {
       memset(m,0,sizeof(m));
       int i,j,t;
       for(i=0;i<4;i++)
        for(j=1;j<8;j++)
        {
            scanf("%d",&t);
            m[i][j]=(char)t;
            if(t%10==1) swap(m[i][j],m[(t/10)-1][0]);
        }
       printf("%d\n",bfs());
   }
}


 

最後更新:2017-04-02 22:15:46

  上一篇:go 英特爾擬明年量產22納米移動芯片
  下一篇:go 英特爾低功耗數據中心芯片獲Facebook青睞