zoukankan      html  css  js  c++  java
  • CDOJ1669 棋盘游戏 [A*]

      这题要用到A*。每个状态N记录个f(N)值,等于从初始状态走到该状态的实际花费g(N)+从该状态到目标状态花费的估计值h(N)。h(N)要小于等于从该状态到目标状态的实际花费。h(N):棋盘上剩余点到出口的曼哈顿距离之和。
      在BFS时,优先考虑f(N)值小的,在f(N)相同时,考虑当前花费g(N)小的。为了每次找到f(N)最小的点,可以用堆(STL中的优先队列)来保存状态。
      状态表示:最多四个棋子,坐标最大是n(n<=6),所以可以用一个整数来表示,相当于n进制数。
      BFS时的状态扩展就很简单了,每个棋子都可向四个方向走一步,判断走的位子是否在棋盘内,是否是空的,是否和其他棋子相邻。每次走后最小的棋后判断是否在出口,是的话就拿掉了。

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<string>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<deque>
    #include<queue>
    #include<vector>
    using namespace std;
    
    typedef struct{
        int f,num,t;
        int loc[4];
    }node;
    
    int check[2000000],n,m,a[8][8],exitloc,mod;
    
    struct cmp{
        bool operator()(const node& a,const node& b){
            if(a.f>b.f) return true;
            if(a.f==b.f && check[a.num]>check[b.num]) return true;
            return false;
        }
    };
    priority_queue<node,vector<node>,cmp> Q;
    
    int trans(node nd,int m){
        int num=0,i;
        for(i=0; i<m; i++){
            num*=mod;
            num+=nd.loc[i];
        }
        return num;
    }
    
    void ini(int n,int m){
        int k=1,i,j;
        for(i=0; i<m; i++) k*=mod;
        for(i=0; i<=k; i++) check[i]=0;
        for(i=0; i<n; i++)
            for(j=0; j<n; j++)
                a[i][j]=0;
    }
    
    int H(node nd){
        int i,num=0,k;
        for(i=0; i<m; i++) {
            k=nd.loc[i];
            if(k!=0)
                num+=abs((k-1)/n - (exitloc-1)/n) + abs((k-1)%n - (exitloc-1)%n);
        }
        return num;
    }
    
    void BFS(){
        int k,i,j,xx,yy,x,y,min,num2,t;
        node nd,nd2;
        while(!Q.empty()){
            nd=Q.top();
            Q.pop();
            if(check[0]>0)return;
            min=m;
            for(i=0; i<m; i++){
                k=nd.loc[i];
                if(k==0) continue;
                a[(k-1)/n][((k-1)%n)]=i+1;
                if(i+1<min) min=i+1;
            }
            for(i=min-1; i<m; i++){
                k=nd.loc[i];
                xx=(k-1)/n;
                yy=(k-1)%n;
                a[xx][yy]=0;
                for(j=0; j<4; j++){
                    x=xx; y=yy;
                    if(j==0)
                        x--;
                    else if(j==1)
                        x++;
                    else if(j==2)
                        y--;
                    else if(j==3)
                        y++;
                    if(x>=0 && x<n && y>=0 && y<n && a[x][y]==0)
                    if((x==0 || a[x-1][y]==0) && (y==0 || a[x][y-1]==0) && (x==n-1 || a[x+1][y]==0) && (y==n-1 || a[x][y+1]==0)){
                        nd2=nd;
                        nd2.loc[i]=x*n+y+1;
                        t=0;
                        if(i==min-1 && x*n+y+1==exitloc) {nd2.loc[i]=0; t=1;}
                        num2=trans(nd2,m);
                        if(check[num2]>0) continue;
                        check[num2]=check[nd.num]+1;
                        nd2.num=num2;
                        nd2.t=nd.t-t;
                        nd2.f=H(nd2)+check[nd2.num];
                        Q.push(nd2);
                    }
                }
                a[xx][yy]=i+1;
            }
            for(i=0; i<m; i++){
                k=nd.loc[i];
                if(k==0) continue;
                a[(k-1)/n][((k-1)%n)]=0;
            }
        }
    }
    
    int main()
    {
        int T,i,j,k;
        char s[10],ch;
        node nd;
        cin>>T;
        while(T--) {
            scanf("%d %d",&n,&m);
            while(!Q.empty())Q.pop();
            mod=n*n+1;
            gets(s);
            for(i=0; i<n; i++)
            {
                gets(s);
                for(j=0; j<n; j++)
                    if(s[j]=='x')
                        exitloc = i*n + j + 1;
                    else if(s[j]>='1' && s[j]<='0'+m)
                        nd.loc[s[j]-'1'] = i*n + j + 1;
            }
            ini(n,m);
            k=trans(nd,m);
            check[k]=1;
            nd.num=k;
            nd.f=H(nd)+check[nd.num];
            nd.t=m;
            Q.push(nd);
            BFS();
            printf("%d\n",check[0]-1);
        }
        return 0;
    }

     

  • 相关阅读:
    【Lintcode】112.Remove Duplicates from Sorted List
    【Lintcode】087.Remove Node in Binary Search Tree
    【Lintcode】011.Search Range in Binary Search Tree
    【Lintcode】095.Validate Binary Search Tree
    【Lintcode】069.Binary Tree Level Order Traversal
    【Lintcode】088.Lowest Common Ancestor
    【Lintcode】094.Binary Tree Maximum Path Sum
    【算法总结】二叉树
    库(静态库和动态库)
    从尾到头打印链表
  • 原文地址:https://www.cnblogs.com/Lattexiaoyu/p/2507989.html
Copyright © 2011-2022 走看看