HDU 1043 A*与康托

恩。。。刚刚AC,心情是。。。。。。。“叫你作叫你作叫你作!!!!!!……………………”

其实。。。这一个代码真的DEBUG了很久我觉得。。。然后发现了如下问题,并且是我第二次再敲的时候还有同样的错误!!不知悔改啊啊啊。。。

第一个是在用map[hash]初始化的时候,我是定了-1为初值,原先为了鉴别初值,就没有改变init map的hash值,以为这样在输出路径的时候方便找出来。(不就是懒得改值嘛!)然后。。结果!!这样就等于初值的hash并没有使用过,于是在第一次DFS的时候,,初值又被纳入队列中了!!!!fuck!!!关键是。。第一次的时候被我在一个月黑风高的晚上发现了,然后debug完高高兴兴睡觉了,结果第二天完全忘记了错在哪里!!!!然后第二遍敲的时候就悲剧了!!!

第二个是要注意在算hash的时候要把x的状态也算进去。这样的状态才是完整的,不然肯定会出现冲突。

然后记得初始化,,,,,恩。。还有对于字符串这一类的题目,设计的样例一定要和题目的格式一样。。。这里坑了好久QAQ捂脸。


康托展开是对于全排列这一类的hash很有效,貌似不会出现冲突。但是个数要比较小,不然也容易爆。

对于A*算法,我觉得理解了BFS,就没什么问题了,只是加了一个条件而已。

话说这一题用g++居然跑的还快些。

#include 
#include 
#include 
#include 
using namespace std;
int f[9]={1,1,2,6,24,120,720,5040,40320};
int cmp[4][2]={0,1,0,-1,1,0,-1,0};
char tar[3][3]={'1','2','3','4','5','6','7','8','x'};
class node
{
public:
    int x,y,h,g;
    char map[5][5];
    int hash;
    
    friend bool operator < (const node &x,const node &y)  //优先级必须是这样的,否则有错
    {
        if(x.h+x.g==y.g+y.h) return x.g>y.g;
        return x.h+x.g>y.g+y.h;
    }
    void print()
    {
        printf("h=%d g=%d hash=%d\n",h,g,hash);
        for(int i=0;i<3;i++) {for(int j=0;j<3;j++) printf("%c ",map[i][j]);printf("\n");}
    }
};
class nodee
{
public:
    int val,op;
    nodee()
    {
        val=op=0;
    }
}map[500000];
int check(node p)
{
    int i,j,k;
    int cout=0;
    for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
        {
            if(p.map[i][j]=='x') continue;
            for(k=0;kp.map[i][j]) cout++;
            }
        }
    }
    return cout%2;
}
int geth(node p)
{
    int i,j,k;
    int cout=0;
    for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
        {
            if(p.map[i][j]=='x') continue;
            k=p.map[i][j]-'1';
            cout+=abs(k/3-i)+abs(k%3-j);
        }
    }
    return cout;
}
int gethash(node p)
{
    int i,j,k=0;
    char a[9];
    int sum=0;
    for(i=0;i<3;i++)
        for(j=0;j<3;j++) a[k++]=p.map[i][j];
    for(i=0;i<9;i++)
    {
        k=0;
        for(j=0;ja[i]) k++;
        sum+=k*f[i];
    }
    return sum;
}
void print(node p)
{
    int i;
    i=p.hash;
    string ans;
    while(i!=-2)
    {
        //cout<<"i="<=0;ii--) printf("%c",ans[ii]);printf("\n");
}
int judge(node p)
{
    int i,j,k;
    for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
        {
            //   printf("[%c %c] ",tar[i][j],p.map[i][j]);
            /*if(p.map[i][j]=='x') continue;
             k=p.map[i][j]-'0';
             if(k!=i*3+j+1) return 0;*/
            if(p.map[i][j]!=tar[i][j]) return 0;
        }//printf("\n");
    }
    //  cout<<"??!!!"<que;
    init.g=0;
    init.h=geth(init);
    init.hash=gethash(init);
    map[init.hash].val=-2;
    que.push(init);
    while(!que.empty())
    {
        node p=que.top(),tmp;
        que.pop();
        if(judge(p)) {//printf("map[311477]=%d  map[311741]=%d\n",map[311477].val,map[311741].val);
            print(p);//cout<<"??"<2||tmp.y<0||tmp.y>2) continue;
            tmp.map[p.x][p.y]=tmp.map[tmp.x][tmp.y];
            tmp.map[tmp.x][tmp.y]='x';
            tmp.hash=gethash(tmp);
            if(map[tmp.hash].val!=-1||check(tmp)) continue;
            map[tmp.hash].val=p.hash;
            map[tmp.hash].op=i+1;
            tmp.g++;tmp.h=geth(tmp);
            que.push(tmp);
            //    printf("map[%d]=%d\n",tmp.hash,map[tmp.hash]);
            //   tmp.print();
        }
    }
    
}
void clear()
{
    for(int i=0;i<500000;i++) map[i].val=map[i].op=-1;
}
int main()
{
    char s[50];
    while(gets(s))
    {
        clear();
        char ss[10];
        int i;
        int top=0;
        node init;
        for(i=0;s[i]!='\0';i++) if(s[i]<='9'&&s[i]>='0'||s[i]=='x') ss[top++]=s[i];
        // if(top==0) {printf("\n");break;}
        for(i=0;i


你可能感兴趣的:(搜索。)