首页 > 其他分享 >AOJ0121(Seven Puzzle, BFS+Cantor+逆向思维)

AOJ0121(Seven Puzzle, BFS+Cantor+逆向思维)

时间:2023-08-23 10:05:42浏览次数:48  
标签:map Seven int Puzzle BFS ++ zero result factor


参考
康托展开

自己真的一点头绪都没有,根据前面的大神博客自己几乎100%复制了一个,但是还是WA,觉得还是出在选方向时的判断上面。

Cantor感觉这个可以作为模板,状态压缩的一个思路。

还有就是BFS特点:
1.从一个起点到一个终点
2.起点和终点可以互相到达,双向的

//#define LOCAL

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define SIZE 50000

using namespace std;

int map[8];
int factor[8];
int result[SIZE];
int dir[] = {-1, 1, -4, 4};

int cantor(){
    int ans = 0;

    for(int i = 0; i < 8; i++){
        int num = 0;
        for(int j = i + 1; j < 8; j++){
            if(map[i] > map[j])
                num++;
        }

        ans += factor[7 - i] * num;
    }

    return ans;
}

void inv_cantor(int num){
    bool visited[8] = {false};

    for(int i = 0; i < 8; i++){
        int divv = num / factor[7 - i];
        num %= factor[7 - i];

        int j;
        for(j = 0; j < 8; j++){
            if(visited[j] == false){
                if(divv == 0)
                    break;
                divv--;
            }
        }

        map[i] = j;
        visited[j] = true; 
    }
}

void init(){
    factor[0] = 1;
    for(int i = 1; i < 8; i++)
        factor[i] = factor[i - 1] * i;

    memset(result, 0, sizeof(result));

    /*for(int i = 0; i < 8; i++)
        printf("%d ", factor[i]);
    printf("\n");*/
}

inline void updata(queue<int> &q, int cur,int p0,int p1)
{
    swap(map[p0], map[p1]);
    int s = cantor();
    if(!result[s]){
        result[s] = result[cur]+1;
        q.push(s);
    }
    swap(map[p0], map[p1]);
}

void bfs(){
    result[0] = 1;
    queue<int> q;
    q.push(0);

    while(!q.empty()){
        int temp = q.front();
        q.pop();

        inv_cantor(temp);
        /*for(int i = 0; i < 8; i++)
            printf("%d ", map[i]);
        printf("\n");*/

        int zero_pos;
        for(int i = 0; i < 8; i++){
            if(map[i] == 0){
                zero_pos = i;
                break;
            }
        }

        int r = zero_pos%4;
        if(r) {
            updata(q, temp,zero_pos-1,zero_pos);
        }
        if(r<3){
            updata(q, temp,zero_pos+1,zero_pos);
        }
        updata(q, temp,zero_pos,zero_pos+(zero_pos>3?-4:4));
        /*for(int i = 0; i < 4; i++){
            int new_pos = zero_pos + dir[i];

            if(0 <= new_pos && new_pos < 8 
                && !(zero_pos == 2 && new_pos == 3) &&
                !(zero_pos == 3 && new_pos == 2)){
                swap(map[zero_pos], map[new_pos]);

                int r = cantor();
                if(result[r] == 0){
                    result[r] = result[temp] + 1;
                    q.push(r);
                }

                swap(map[zero_pos], map[new_pos]);
            }
        }*/
    }

}

int main(void){
#ifdef LOCAL
    freopen("data.in", "r", stdin);
#endif
    init();
    bfs();

    while(scanf("%d", &map[0]) != EOF){
        for(int i = 1; i < 8; i++)
            scanf("%d", &map[i]);

        int x = cantor();
        printf("%d\n", result[x] - 1);
    }

    return 0;
}


标签:map,Seven,int,Puzzle,BFS,++,zero,result,factor
From: https://blog.51cto.com/u_8999467/7199306

相关文章

  • AOJ0558(cheese, BFS)
    typicalBFSusage:firstuse2array,oneforrecordmap,theotherforshortestpath/flagvisit.BFSfeature:theshortestpathfromonetotheother,justonepoint!!!!(单源路)//#defineLOCAL#include<cstdio>#include<cstring>#include<......
  • perlapp BFS格式分析
    perlappBFS格式分析1、加载资源中加密的BFSLoadResource_BFS_406670LPVOID*__fastcallLoadResource_BFS_406670(char*Source){//[COLLAPSEDLOCALDECLARATIONS.PRESSKEYPADCTRL-"+"TOEXPAND]v2=(BFS**)malloc(0x28ui64);v3=v2;if(!v2)r......
  • bfs 双向宽搜
     1、迷宫问题,找最短路:可以同时从起点和终点进行bfs,两个方向搜索的新节点分别存在不同的队列中的,若新节点在对面的状态集合中出现过,说明相遇了。2、很多bfs问题,都可以用双向宽搜,提高效率。3、分油问题,能不能用双向宽搜呢?3个无刻度的油瓶的容量是1073,其中分别有油10,0,0......
  • Non-Puzzle: Segment Pair
    Non-Puzzle:SegmentPair时间限制(普通/Java):2000MS/4000MS内存限制:262144KByte描述输入输出样例输入3146725351357样例输出2思路枚举区间左端点x,则要满足区间的交包含x,并且不包含x−1。考虑计算包含x的方案数,则每对区间的贡献......
  • Non-Puzzle: Segment Pair
    题意给n对区间,要求每对区间恰好选一个使得选出来的n个区间有交集,问有多少方案数1≤n,l1,l2,r1,r2≤5×10^5思路枚举结果以i为左端点的区间的数量,对于每个i,以i为左端点的区间的数量=结果包含i的数量-结果同时包含i和i-1的数量.对于每对区间,如果两个区间没有重叠部分,那么这......
  • 2023牛客暑期多校训练营9--I Non-Puzzle: Segment Pair
    思路:直接枚举区间左端点,用一个cnt数组表示当前端点l,r或者L,R存在1个还是2个或者0个。用一个sum变量记录有多少段区间覆盖了该端点,如果sum==n那么这个端点就有了贡献。更详细的看代码注释。#include<bits/stdc++.h>usingnamespacestd;#defineIOSios::sync_with_stdio(fa......
  • 2023牛客多校第九场 D Non-Puzzle: Error Permutation
    题意给定一个长度为n的序列,计算有多少个子区间满足子区间第K小的数不在子区间第K位。 找出所有不满足条件的区间。枚举所有的ai和左端点al,找出满足ai是区间[l,r]中第r-l+1小的右端点r,则右端点r一定是一段区间。例如   342165         l i ......
  • 23牛客多校9 I Non-Puzzle: Segment Pair
    也许更好的阅读体验\(\mathcal{Description}\)给\(n\)对区间,要求每对区间恰好选一个使得选出来的\(n\)个区间有交集,问有多少方案数\(1\len,l_i,r_i\le5×10^5\)\(\mathcal{Solution}\)注意到区间的值域也是\(5×10^5\),考虑从值域入手,也就是枚举每个点看有多少种方案使最后......
  • LeetCode 周赛上分之旅 # 37 多源 BFS 与连通性问题
    ⭐️本文已收录到AndroidFamily,技术和职场问题,请关注公众号[彭旭锐]和BaguTreePro知识星球提问。学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场LeetCode周赛的解题报告,一......
  • 搜索(DFS和BFS)
    深搜是我最早学的算法,当然现在还没有信手拈来就是了。。。为了更好地学树和图,只能回来刷搜索了。。。。。我已经搜了一天了啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊(疯癫)首先是今天去刷的八皇后问题,特别经典的搜索题,我记得我有一天深夜学算法就看了这个八皇后问题,其实深搜和广搜......