zoukankan      html  css  js  c++  java
  • HDU1043逆向bfs打表

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

    因为结果都是“12345678x”,目标状态固定,所以可以列举所有的可能,然后用哈希表标志,然后直接调用

    /*
    PKUoj
    Source Code
    
    Problem: 1077        User: 297752873
    Memory: 6728K        Time: 313MS
    Language: C        Result: Accepted
    Source Code
    */
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #define QueueSize 370000
    int f[8] = {1, 2, 6, 24, 120, 720, 5040, 40320};//用于全排列的哈希函数的构建 
    char end[10],ch[4]={'d','u','r','l'};//开始和结束的状态 
    int ans[400000],hash[400000];//开始和结束的点 
    struct eight
    {
           char str[10];//结点矩阵 
           int k ;//空格的位置 
           int fx;//移动的方向1表示上,2表示下, 3表示左,4表示右
           int fa;//父节点   
    }s[370000];
    typedef struct
    {
        int front;
        int rear;
        int count;
        int data[370000];
    }CirQueue;
        CirQueue Q;//使用队列,队列里保存的是各状态的下标 
    
    void InitQueue(CirQueue *Q)//建队 
    {
        Q->front=Q->rear=0;
        Q->count=0;
    }
    int QueueEmpty(CirQueue *Q)//判队是否空 
    {
        return Q->count==0;
    }
    void EnQueue(CirQueue *Q,int x)//入队 
    { 
        
            Q->count++;
            Q->data[Q->rear]=x;
            Q->rear=(Q->rear+1)%QueueSize;
    
    }
    int DeQueue(CirQueue *Q)//出队,并删除队首元素 
    {
        int temp;
            temp=Q->data[Q->front];
            Q->count--;
            Q->front=(Q->front+1)%QueueSize;
            return temp;
    }
    
    int get_hash_code(char str[]) //计算全排列哈希值 
    {  
        int i, j;  
        int ret = 0, cnt;  
        for(i = 1; i < 9; ++i)  
        {  
            cnt = 0;  
            for(j = 0; j < i; ++j)  
                if(str[j] > str[i])  
                    cnt++;  
            ret += cnt*f[i-1];  
        }  
        return ret;  
    }  
    void print(int x)//若发现可完成,则利用父节点逐个输出 
    {
         //printf("find
    ");
                while (x!=s[x].fa)
                {
                    printf("%c",ch[s[x].fx-1]);
                    x=s[x].fa;
                }
                printf("
    ");
    } 
    int bfs()
    {
        int w,k,has;
        char temp,a[10];//这些作为中间量 
        memset(hash,0,sizeof(hash));
        has=get_hash_code("123456780");
        s[has].fa=has;//第一个的父节点赋为自己 
        strcpy(s[has].str,"123456780");
        s[has].k=8;    
        hash[has]=1;
        InitQueue(&Q);
        /*if(strcmp(s[beginf].str,end)==0)
        {
           printf("lr
    ");
           return 0;
        }*/
        EnQueue(&Q,has);
        while(!QueueEmpty(&Q))
        {
            w=DeQueue(&Q);//取队首元素 
           /* if(strcmp(s[w].str,end)==0)
            {
               print(w);
               return 0;
            } */
            strcpy(a,s[w].str);
               k=s[w].k;//保留空格的位置 
               if (k>=3)//可上移的 
                {
                    temp=a[k];a[k]=a[k-3];a[k-3]=temp;
                    has=get_hash_code(a);
                    if (hash[has]==0)
                    {
                        strcpy(s[has].str,a);
                        s[has].fx=1;
                        s[has].fa=w;
                        s[has].k=k-3;
                        hash[has]=1;
                        EnQueue(&Q,has);
                    }
                    temp=a[k];a[k]=a[k-3];a[k-3]=temp;//复原成原来的样子,以便下一个移动可以使用 
                }
                if (k%3!=0)//可左移的 
                {
                    temp=a[k];a[k]=a[k-1];a[k-1]=temp;
                    has=get_hash_code(a);
                    if (hash[has]==0)
                    {
                        strcpy(s[has].str,a);
                        s[has].fx=3;
                        s[has].fa=w;
                        s[has].k=k-1;
                        hash[has]=1;
                        EnQueue(&Q,has);
                    }
                    temp=a[k];a[k]=a[k-1];a[k-1]=temp;
                }
                if (k%3!=2)//可右移的 
                {
                    temp=a[k];a[k]=a[k+1];a[k+1]=temp;
                    has=get_hash_code(a);
                    if (hash[has]==0)
                    {
                        strcpy(s[has].str,a);
                        s[has].fx=4;
                        s[has].fa=w;
                        s[has].k=k+1;
                        hash[has]=1;
                        EnQueue(&Q,has);
                    }
                    temp=a[k];a[k]=a[k+1];a[k+1]=temp;
                }
                if (k<6)//可下移的 
                {
                    temp=a[k];a[k]=a[k+3];a[k+3]=temp;
                    has=get_hash_code(a);
                    if (hash[has]==0)
                    {
                        strcpy(s[has].str,a);
                        s[has].fx=2;
                        s[has].fa=w;
                        s[has].k=k+3;
                        hash[has]=1;
                        EnQueue(&Q,has);
                    }temp=a[k];a[k]=a[k+3];a[k+3]=temp;
                }
                
        }
    }
    
    int main()
    {
        int i,j,m,l;
        bfs();
        while(gets(end)!=NULL)
        { 
        j=0;
        l=strlen(end);
        for(i=0;i<l;i++){
        if(end[i]==' ')continue;
           if(end[i]=='x')
           {
              end[j]='0';
              j++;
           }else end[j++]=end[i];
        }
           end[j]='';
        m=get_hash_code(end);
        //printf("%s 
    ",end);
           if(hash[m])
              print(m);
           else 
             printf("unsolvable
    ");
          // system("pause");
          } 
        return 0;
    } 
    View Code
  • 相关阅读:
    1856: [Scoi2010]字符串(Catalan数)
    11.6NOIP模拟赛
    bzoj1257[CQOI2007]余数之和(除法分块)
    11.5NOIP模拟赛
    bzoj1048(记忆化搜索)
    置顶公告+更新日志
    CF585F Digits of Number Pi
    [SHOI2007]善意的投票
    [HEOI2015]最短不公共子串
    树形背包复杂度+P3177 [HAOI2015]树上染色
  • 原文地址:https://www.cnblogs.com/huzhenbo113/p/3231286.html
Copyright © 2011-2022 走看看