状态结点查重的问题

l r j lrj lrj老师给我们三种解决办法,对于一个节点的查重。
这里拿八数码问题中的状态查重来介绍:
数组表示了当前状态。

编码和解码


将排列变成整数:设计一套排列的编码和解码,把 0 − 8 0-8 08的全排列和 0 − 362879 0-362879 0362879的整数一一对应。
然而具体实现的对应并没有看懂。

int vis[362880],fact[9];
void init_lookup_table(){
    fact[0]=1;
    for(int i=1;i<9;i++)fact[i]=fact[i-1]*i;
}
int try_to_insert(int s){
    int code=0;
    for(int i=0;i<9;i++){
        int cnt=0;
        for(int j=i+1;j<9;j++)if(st[s][j]<st[s][i])cnt++;
        code+=face[8-i]*cnt;
    }
    if(vis[code])return 0;
    return vis[code]=1;
}

哈希表


哈希技术:将结点变成整数,并映射到一个区间内,如果哈希相同的就插入一个链表中。
查询的时候在哈希值对应的链表中查询。(这个方法最佳/不过链表可能很长,要求哈希函数足够优秀,区间长度也最好是大素数)

const int hashsize = 1000003;
int head[hashsize],next[maxstate];
void init_lookup_table(){memset(head,0,sizeof(head));}
int hash(State& s){
    int v=0;
    for(int i=0;i<9;i++)v=v*10+s[i];
    return v%hashsize;
}
int try_to_insert(int s){
    int h=hash(st[s]);
    int u=head[h];
    while(u){
        if(memcmp(st[u],st[s],sizeof(st[s]))==0)return 0;
        u=next[u];
    }
    next[s]=head[h];
    head[h]=s;
    return 1;
}

STL


可以使用 m a p , s e t map,set map,set直接记录状态,或者将状态暴力转换成数(可以存 l o n g l o n g long long longlong)
最后查询判断即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值