zoukankan      html  css  js  c++  java
  • POJ 1077 eight DBFS

    和HDU1043一样的题目,这次用DBFS实现。

    感觉写的还是不错的,中间一些细节错误了很多次。

    具体见代码。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <string>
    #include <cmath>
    #include <cstring>
    #include <queue>
    #include <set>
    #include <vector>
    #include <stack>
    #include <map>
    #include <iomanip>
    #define PI acos(-1.0)
    #define Max 500005
    #define inf 1<<28
    #define LL(x) (x<<1)
    #define RR(x) (x<<1|1)
    #define Rep(i,s,t) for(int i=(s);i<=(t);++i)
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    #define mp(a,b) make_pair(a,b)
    
    using namespace std;
    struct kdq
    {
        string op;
        char Map[4][4] ;
        int x ,y ;
        void show()
        {
            Rep(i,0,2)
            {
                Rep(j,0,2)
                cout <<char(Map[i][j] + '0');
                cout <<endl;
            }
            cout <<endl;
        }
    } ;
    string state[Max] ;
    
    int fac[12] = { 0, 1, 2, 6, 24, 120,720, 5040, 40320, 362880, 3628800} ;
    int kangtuo(kdq a)
    {
        int ans = 0 ;
        Rep(i,0,8)
        {
            int num = 0 ;
            Rep(j,i + 1 ,8)
            {
                if(a.Map[i / 3][i % 3] > a.Map[j / 3 ][j % 3])
                    num ++ ;
            }
            ans += num * (fac[8 - i]) ;
        }
        return ans ;
    }
    int vis[Max] ;
    int mx[4] = {0,0,1,-1} ;
    int my[4] = {1,-1,0,0} ;
    char opp[4] = {'r' ,'l','d','u'} ;//从起点开始搜索时的交换顺序
    char dopp[4] = {'l','r','u','d'} ;//从终点开始搜索时的交换顺序
    int inmap(kdq a )
    {
        if(a.x >= 0 && a.y <3 && a.x < 3 && a.y >= 0)return 1;
        return 0 ;
    }
    
    string bfs(kdq s )
    {
        queue<kdq>q ;
        kdq init ;
        init.Map[0][0] = 1 ;
        init.Map[0][1] = 2 ;
        init.Map[0][2] = 3 ;
        init.Map[1][0] = 4 ;
        init.Map[1][1] = 5 ;
        init.Map[1][2] = 6 ;
        init.Map[2][0] = 7 ;
        init.Map[2][1] = 8 ;
        init.Map[2][2] = 9 ;
        init.x = 2 ;
        init.y = 2 ;
        init.op.clear() ;
        q.push(s) ;//起点
        q.push(init) ;//终点
        int ss = kangtuo(s) ;
        vis[ss] = 2 ;//将从起点开始遍历到的点置为2
        ss = kangtuo(init) ;
        vis[ss] = 1 ;//将从终点开始遍历到的点置为1
        while(!q.empty())
        {
            kdq temp = q.front() ;
            q.pop() ;
            int cc = kangtuo(temp) ;
            Rep(i,0,3)
            {
                kdq next = temp ;
                next.x = temp.x + mx[i] ;
                next.y = temp.y + my[i] ;
                if(inmap(next))
                {
                    swap(next.Map[next.x][next.y] ,next.Map[temp.x][temp.y]) ;
                    int num = kangtuo(next) ;
                    if(!vis[num] )//如果未遍历过该点
                    {
                        vis[num] = vis[cc] ;
                        if(vis[num] == 1)//如果是终点遍历出来的点
                            next.op += dopp[i] ;
                        else//同理
                            next.op += opp[i] ;
                        state[num] = next.op ;//记录当前的路径
                        q.push(next) ;
                    }
                    else if(vis[num] != vis[cc])//如果该点被起点和终点都遍历到
                    {
                        string c1 ,c2 ;
                        if(vis[num] == 1)
                            c1 = state[num] ,c2 = state[cc] + opp[i];
                        else c1 = state[cc] + dopp[i] ,c2 = state[num] ;
                        reverse(c1.begin() ,c1.end()) ;//注意从终点开始遍历的顺序得取反
                        return c2 + c1 ;//那么返回该点的顺序,即为起点到终点的顺序
                    }
                }
            }
        }
        return "unsolvable" ;
    }
    
    char a[10000] ;
    int main()
    {
        while(gets(a))
        {
            int l = strlen(a) ;
            kdq now ;
            int tx = 0 ;
            int numx ,numy ;
            Rep(i,0,l - 1)
            {
                if(a[i] >= '0' && a[i] <= '8')
                {
                    now.Map[tx / 3] [tx % 3] = a[i] - '0' ;
                    tx ++ ;
                }
                else if(a[i] == 'x')
                {
                    now.Map[tx / 3][tx % 3] = 9 ;
                    numx = tx / 3 ;
                    numy = tx % 3 ;
                    tx ++ ;
    
                }
                if(tx >= 9)break ;
            }
            mem(vis,0) ;
            now.x = numx ;
            now.y = numy ;
            now.op.clear() ;
            printf("%s\n",bfs(now).c_str()) ;
        }
        return 0;
    }
    


  • 相关阅读:
    函数指针与函数声明
    long和int的区别
    pthread_create传递参数
    C语言中的static 详细分析
    linux 读写锁应用实例
    linux使用读写锁pthread_rwlock_t
    linux的<pthread.h>
    时间:UTC时间、GMT时间、本地时间、Unix时间戳
    等号赋值与memcpy的效率问题
    单链表带头结点&不带头结点
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3028392.html
Copyright © 2011-2022 走看看