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;
}
posted on 2011-09-12 21:47  猿类的进化史  阅读(304)  评论(0编辑  收藏  举报