zoukankan      html  css  js  c++  java
  • 八位数

    我真的服了, 这题解法是真的多

    八位数问题好像还是挺有名的

    题目就是给你一个3*3的矩阵里面填装这 1-8的数字  空了一个格子,我们的目的就是让这个矩阵排列成

    1 2 3

    4 5 6

    7 8 x       x是空出来的

    方法1: 无脑  map<string,bool> mp,bfs,dfs,巴拉巴拉乱敲就是了,反正我这题这个方法过不了

    方法2:把 x看成9,从1 2 3 4 5 6 7 8 9,搜索所有的状态,记录到达所有状态的路径,输入一个起始状态,直接输出路径,好歹能过

    这算是比较笨的办法了,我看到网上有很多A*,双向bfs的,深感自己的弱小

    对于这个当前状态的保存,我们用了一个叫做康拓展开的东西,这个东西就很劲,具体的你可以看一下康拓展开的百度百科,讲的是很详细了

    相当于是做了一个映射

    #include<iostream>
    #include<queue>
    #include<cstring>
    #include<vector>
    #include<cstdio>
    #include<cmath>
    #include<map>
    #include<string>
    using namespace std;
    #define ll long long
    #define se second
    #define fi first
    #define oo 0x3fffffff
    const int maxn = 400000;
    bool hashs[maxn];
    string path[maxn];
    int fac[]={1,1,2,6,24,120,720,5040,40320,362880};
    int dx[4] = {1,-1,0,0};
    int dy[4] = {0,0,1,-1};
    char op[5] = "udlr";
    struct node
    {
        int s[9];
        int pos;
        int val;
        string path;
    };
    int tocon(int a[])
    {
        int x = 0;
        for(int i = 0; i <= 8; ++i)
        {
            int k = 0;
            for(int j = i+1; j <= 8; ++j)
                if(a[j] > a[i]) k ++;
            x += k*fac[9-i-1];
        }
        return x;
    }
    void bfs()
    {
        int num[9];
        memset(hashs,0,sizeof(hashs));
        node st,ed;
        for(int i = 0; i < 9; ++i)
            st.s[i] = i+1;
        st.val = tocon(st.s);
        st.path = "";
        path[st.val] = "";
        hashs[st.val] = true;
        st.pos = 8;
        queue<node> q;
        q.push(st);
        while(!q.empty())
        {
            st = q.front();
            q.pop();
    
            for(int i = 0; i < 4; ++i)
            {
                int xx = st.pos/3+dx[i];
                int yy = st.pos%3+dy[i];
                if(xx >= 0 && xx <= 2 && yy >= 0 && yy <= 2)
                {
                    ed.pos = xx*3 + yy;
                    for(int i = 0; i < 9; ++i)
                        ed.s[i] = st.s[i];
                    //for(int i = 0 ; i < 9; ++i)
                      //  cout << ed.s[i];
                        //cout << endl;
                    swap(ed.s[ed.pos],ed.s[st.pos]);
                    ed.val = tocon(ed.s);
                    if(!hashs[ed.val])
                    {
                        hashs[ed.val] = true;
                        ed.path = op[i] + st.path;
                        path[ed.val] = ed.path;
                        q.push(ed);
                    }
                }
            }
        }
    }
    int main()
    {
        char str[150];
        bfs();
        while(gets(str))
        {
            int s[9];
            int l = 0;
            for(int i = 0; i < strlen(str); ++i)
            {
                if(str[i] <= '9' && str[i] >= '0')
                    s[l++] = str[i] - '0';
                else if(str[i] == 'x')
                    s[l++] = 9;
            }
            int k = tocon(s);
            if(hashs[k]) cout << path[k] << endl;
            else
                cout << "unsolvable" << endl;
        }
    }

    方法3  双向bfs  

    为什么我的双向bfs会超空间啊!不管怎么讲,这个代码还是能够运行的,思路至少是对的,也算是一个方法

    #include<iostream>
    #include<queue>
    #include<cstring>
    #include<vector>
    #include<cstdio>
    #include<cmath>
    #include<map>
    #include<string>
    using namespace std;
    #define ll long long
    #define se second
    #define fi first
    #define oo 0x3fffffff
    const int maxn = 362885;
    bool hashs1[maxn];
    bool hashs2[maxn];
    string path1[maxn];
    string path2[maxn];
    int fac[]={1,1,2,6,24,120,720,5040,40320,362880};
    int dx[4] = {-1,0,0,1};
    int dy[4] = {0,1,-1,0};
    char op1[5] = "urld";
    char op2[5] = "dlru";
    struct node
    {
        int s[9];
        int pos;
        int val;
        //string path;
    };
    int tocon(int a[])
    {
        int x = 0;
        for(int i = 0; i <= 8; ++i)
        {
            int k = 0;
            for(int j = i+1; j <= 8; ++j)
                if(a[j] > a[i]) k ++;
            x += k*fac[9-i-1];
        }
        return x;
    }
    void bfs(int a[9])
    {
        node tmp,t;
        int c = 0;
        queue<node> q1,q2;
        node sc;
        for(int i = 0; i < 9; ++i)
            sc.s[i] = i+1;
        sc.pos=8;
        sc.val = tocon(sc.s);
        //sc.path = "";
        path1[sc.val] = "";
        q2.push(sc);
        for(int i = 0; i < 9; ++i)
        {
            if(a[i] == 9)
                c = i;
            tmp.s[i] = a[i];
        }
        tmp.pos = c;
        tmp.val = tocon(a);
        //tmp.path = "";
        path2[tmp.val] = "";
        q1.push(tmp);
        while(!q1.empty() || !q2.empty())
        {
            int s = q1.size();
            while(s--)
            {
                tmp = q1.front();
                q1.pop();
                int pos = tmp.pos;
                for(int i = 0; i < 4; ++i)
                {
                    int xx = pos/3 + dx[i];
                    int yy = pos%3 + dy[i];
                    if(xx >= 0 && xx <= 2 && yy >= 0 && yy <= 2)
                    {
                        t = tmp;
                        /*cout << "mark1 :" ;
                        for(int i = 0; i < 9; ++i)
                            printf("%d ",t.s[i]);
                        printf("
    ");*/
                        int newpos = xx*3+yy;
                        swap(t.s[pos],t.s[newpos]);
                        t.pos = newpos;
                        t.val = tocon(t.s);
                        path1[t.val] = path1[tmp.val]+op1[i];
                        if(!hashs1[t.val])
                        {
                            if(hashs2[t.val] == true)
                            {
                                //cout << "yes" << endl;
                                cout << path1[t.val] + path2[t.val] << endl;
                                return ;
                            }
                            hashs1[t.val] = true;
                            q1.push(t);
                        }
                    }
                }
            }
    
            s = q2.size();
            while(s--)
            {
                tmp = q2.front();
                q2.pop();
                int pos = tmp.pos;
                for(int i = 0; i < 4; ++i)
                {
                    int xx = pos/3 + dx[i];
                    int yy = pos%3 + dy[i];
                    if(xx >= 0 && xx <= 2 && yy >= 0 && yy <= 2)
                    {
                        t = tmp;
                        /*cout << "mark2 :" ;
                        for(int i = 0; i < 9; ++i)
                            printf("%d ",t.s[i]);
                        printf("
    ");*/
                        int newpos = xx*3+yy;
                        swap(t.s[pos],t.s[newpos]);
                        t.pos = newpos;
                        t.val = tocon(t.s);
                        path2[t.val] = op2[i]+path2[tmp.val];
                        //cout << t.path << endl;
                        if(!hashs2[t.val])
                        {
                            if(hashs1[t.val] == true)
                            {
                                //cout << "no" << endl;
                                cout << path1[t.val] + path2[t.val] << endl;
                                return ;
                            }
                            hashs2[t.val] = true;
                            q2.push(t);
                        }
                    }
                }
            }
        }
        printf("unsolvable
    ");
    }
    int main()
    {
        char str[150];
        //bfs();
        while(gets(str))
        {
            int s[9];
            int l = 0;
            for(int i = 0; i < strlen(str); ++i)
            {
                if(str[i] <= '9' && str[i] >= '0')
                    s[l++] = str[i] - '0';
                else if(str[i] == 'x')
                    s[l++] = 9;
            }
            memset(hashs1,0,sizeof(hashs1));
            memset(hashs2,0,sizeof(hashs2));
            bfs(s);
        }
    }
  • 相关阅读:
    我的Ajax之旅(一):不能加载'AjaxControlToolkit'。。。拒绝访问
    网络编程(一):用C#下载网络文件的2种方法
    Locks
    Threads
    C语言中函数名和struct名可以重名!
    使用#include <pthread.h>
    APUE Chapter 7 (2)main函数的参数
    Creating a shared and static library with the gnu compiler [gcc][转]
    Signals
    APUE Chapter 7(3) – Memory layout of a C program
  • 原文地址:https://www.cnblogs.com/mltang/p/9742744.html
Copyright © 2011-2022 走看看