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;

}

你可能感兴趣的:(T)