• Eight


    poj 1077/hdoj 1043

    题目大意:你懂得

    解决:A*,在poj上数据很弱,后来他们说zoj和hdoj都有这道题,就在过一下,这次数据是多组的,没想到都超时了,原因是

    有无解的情况,关键是如何判断无解的情况,他们说提前都能判断出来,判了两次没盘出来,后来才知道是这样整的:由于一个空格和其他的数字交换位置,若是与同一行交换,逆序数的个数不变(这可是不包含9,就把那个当成空格处理),若是与同一列交换,要么是增加2,要么是减少2,可见奇偶性不变,根据这个可以判断出是否有解,若没有解在a*,因为一定会有解

    顺便推荐一篇好文章 http://hi.baidu.com/benbearlove/blog/item/0c8b68db5ea9c3c8b6fd48a3.html 

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <algorithm>
    using namespace std;
    #define N 362885
    #define in(x,y)  (x>=0 && x< 3 && y>=0 && y<3)
    int endpos[10][2];
    int map[3][3];
    int fact[]={1,1,2,6,24,120,720,5040,40320,362880};
    int dx[]={1,-1,0,0};
    int dy[]={0,0,1,-1};
    int sx,sy;
    bool vis[N];
    char d[]="durl";
    char res[1000];
    int p;
    struct pos
    {
        int dir,pre;
        pos(){}
        pos(int d,int p):dir(d),pre(p){}
    };
    pos path[368225];
    
    struct node
    {
        int map[3][3];
        int id;
        int x,y;
        int fs;
        int gs;
        int hs;
        node(int m[][3],int i,int xx,int yy,int g,int h):id(i),x(xx),y(yy),gs(g),hs(h){memcpy(map,m,sizeof(map));  fs=gs+hs;}
        node(){}
    };
    bool operator < (const node &a,const node &b)
    {//后来将比较函数改成了这个
        if(a.fs!=b.fs)return a.fs>b.fs;
         return a.gs>b.gs;
    }
    int hash(int map[][3])
    {
        int sum=0,cnt;
        for(int i=0;i<9;i++)
        {
            cnt=0;
            for(int j=i+1;j<9;j++)
            if(map[j/3][j%3]<map[i/3][i%3])cnt++;
            sum+=fact[8-i]*cnt;
        }
        return sum;
    }
    int heur(int m[][3])
    {
        int sum=0;
        for(int i=0;i<3;i++)
          for(int j=0;j<3;j++)
           sum+=abs(i-endpos[m[i][j]][0])+abs(j-endpos[m[i][j]][1]);
         return sum;
    }
    int check(int map[][3])
    {
        int cnt=0;
        for(int i=0;i<9;i++)
        {
            if(map[i/3][i%3]==9)continue;
            for(int j=i+1;j<9;j++)
            {
                if(map[j/3][j%3]==9)continue; 
                if(map[j/3][j%3] < map[i/3][i%3])cnt++;
            }
        }
        return cnt;
    }
    bool astar()
    {
        priority_queue<node> q;
        node beg=node(map,hash(map),sx,sy,0,heur(map));
        if(beg.id==0){path[0]=pos(0,-1);return 1;}
        int t=check(map);
        if(t%2)return 0;
        vis[beg.id]=1;
        path[beg.id]=pos(0,-1);
        q.push(beg);
        node now,next;
        while(!q.empty())
        {
            now=q.top();
            q.pop();
           for(int i=0;i<4;i++)
            {  
                next=now;
                next.x=now.x+dx[i];
                next.y=now.y+dy[i];
                  if(in(next.x,next.y))
                {
                        swap(next.map[now.x][now.y],next.map[next.x][next.y]);
                        next.id=hash(next.map);
                        if(vis[next.id])continue;
                        vis[next.id]=1;
                        next.hs=heur(next.map);
                        next.gs++;
                        next.fs=next.hs+next.gs;
                        path[next.id]=pos(i,now.id);
                        if(next.id==0)return 1;
                        q.push(next);
                       
                 }
            }
        }
    
    }
    void print(int t)
    {
        if(path[t].pre>=0)
        {
            print(path[t].pre);
            res[p++]=d[path[t].dir];
        }
    }
    int main()
    {
        int  i,j,k=1;
        for(i=0;i<3;i++)
           for(j=0;j<3;j++)
            endpos[k][0]=i,endpos[k++][1]=j;
        char ch[30];
        while( gets(ch) )
        { 
            memset(vis,0,sizeof(vis));
            i=0,j=0;
            while(ch[i])
            {
                if(ch[i]=='x'){sx=j/3; sy=j%3; map[sx][sy]=9; j++; }
                else if(ch[i]>='0' && ch[i]<='9'){map[j/3][j%3]=ch[i]-'0';j++;}
                i++;
            }
            
            if(astar())
            {
                p=0;
                print(0);
                res[p]='\0';
                puts(res);
            }
            else puts("unsolvable");
        }
        system("pause");
        return 0;
    }
    

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <queue>
    #define N 362885
    using namespace std;
    bool visit[N];
    int st,a[3][3],end;
    int dir[9]={1,1,2,6,24,120,720,5040,40320};
    int endpos[10][2]={0,0,0,0,0,1,0,2,1,0,1,1,1,2,2,0,2,1,2,2};
    int sx,sy;
    int dx[]={1,-1,0,0};
    int dy[]={0,0,1,-1};
    char d[]="durl";
    
    char res[100];
    int p;
    
    struct pos
    {
        char dir;
        int pre;
        pos(){}
        pos(int d,int p):dir(d),pre(p){}
    };
    pos path[N];
    struct node
    {
        int map[3][3];
        int ans;
        int x;
        int y;
        int f;
        int g;
        bool operator <(const node & a)const 
        {
            return  f>a.f;
        }
    };
    int hash(int map[][3])
    {
        int cnt,sum=0;
        for(int i=0;i<9;i++)
        {
            cnt=0;
            for(int j=i+1;j<9;j++)
            if(map[j/3][j%3] < map[i/3][i%3])cnt++;
            sum+=dir[8-i]*cnt;
        }    
        return sum;
    }
    int abs(int x){  return x<0?(-x):x; }
    int h(int map[][3])
    {
        int sum=0;
        for(int i=0;i<3;i++)
          for(int j=0;j<3;j++)
          sum+=abs(i-endpos[map[i][j]][0])+abs(j-endpos[map[i][j]][1]);
        return sum;  
    }
    void bfs()
    {
        int ans;
        priority_queue<node> q;
        node cur,next;
        memcpy(cur.map,a,sizeof(a));
        cur.ans=st=hash(a);
        path[cur.ans]=pos(0,-1);
        visit[cur.ans]=1;
        if(st==end)return;
        cur.x=sx;
        cur.y=sy;
        cur.f=h(a);
        cur.g=0;
        q.push(cur);
        while(!q.empty())
        {
            cur=q.top();
            q.pop();
            for(int i=0;i<4;i++)
            { 
                next=cur;
                next.x=cur.x+dx[i];
                next.y=cur.y+dy[i];
                if(next.x<0 || next.x>=3 || next.y <0 || next.y >=3)continue;
                next.map[cur.x][cur.y]=next.map[next.x][next.y];
                next.map[next.x][next.y]=9;
                ans=hash(next.map);
                if(visit[ans])continue;
                visit[ans]=1;
                next.g++; 
                next.f= next.g+h(next.map);
                next.ans=ans;
                  path[next.ans]=pos(d[i],cur.ans);
                if(ans==end)return;
                q.push(next);
            }
         }
    }
    
    int check(int map[][3])
    {
        int cnt=0;
        for(int i=0;i<9;i++)
        {
            if(map[i/3][i%3]==9)continue;
            for(int j=i+1;j<9;j++)
            {
                if(map[j/3][j%3]==9)continue; 
                if(map[j/3][j%3] < map[i/3][i%3])cnt++;
            }
        }
        return cnt;
    }
    
    void print(int t)
    {
        if(path[t].pre>=0)
        {
            print(path[t].pre);
            res[p++]=path[t].dir;
        }
    }
    int main()
    {
        int i,j,ans;
        char str[50];
        while( gets(str) )
        {
            memset(visit,0,sizeof(visit));
            i=0,j=0;
            while(str[i])
            {
                if(str[i]=='x'){sx=j/3; sy=j%3; a[sx][sy]=9; j++; }
                else if(str[i]>='0' && str[i]<='9'){a[j/3][j%3]=str[i]-'0';j++;}
                i++;
            }
            end=0;
            ans=check(a);
            if(ans%2){puts("unsolvable"); continue; }
            bfs();
            j=0;
            p=0;
            while(j>=0)
            {
                res[p++]=path[j].dir;
                j=path[j].pre;
            }
            p--;
            for(int i=p-1;i>=0;i--)printf("%c",res[i]);
            printf("\n");
            
        }
        system("pause");
        return 0;
    }
    
  • 相关阅读:
    Linux中OCI开发库的配置
    makefile中的gcc -o $@ $^是什么意思?
    【转】gcc中的-w -W和-Wall选项
    【转】Linux查看系统是32位还是64位方法总结
    【转】gcc命令中参数c和o混合使用的详解
    Python2.7设置在shell脚本中自动补全功能的方法
    Python3设置在shell脚本中自动补全功能的方法
    Pyqt图标下载网站
    如何使QLineEdit禁止编辑
    python偏函数的运用
  • 原文地址:https://www.cnblogs.com/hpustudent/p/2174233.html
Copyright © 2020-2023  润新知