• POJ 1184 聪明的打字员


    简直难到没朋友。

    双向bfs + 剪枝。

    剪枝策略:

    对于2--5位置上的数,仅仅有当光标在相应位置时通过swap ,up。down来改变。那么当当前位置没有达到目标状态时,left和right无意义。

    好了。仅仅剪掉这里就过掉了。。。

    还有比較炫酷的方法实现枚举720种排列。

    。。

    然后状压什么的。。。

    功力不够全然看不懂。

    。。。

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <queue>
    #include <cmath>
    #include <stack>
    #include <map>
    
    #pragma comment(linker, "/STACK:1024000000");
    #define EPS (1e-8)
    #define LL long long
    #define ULL unsigned long long
    #define _LL __int64
    #define _INF 0x3f3f3f3f
    #define Mod 9999991
    
    using namespace std;
    
    short int mark[1000000][7][2];
    
    struct Q
    {
        int ans,sta,site,fl;
    };
    
    int s[10];
    
    int pre[] = {1000000,100000,10000,1000,100,10,1};
                //     0      1     2    3   4  5 6
    inline int Cal(int num,int site,int ch)
    {
        int temp = (num/pre[site])%10 + ch;
        if(0 <= temp && temp <= 9)
            return num/pre[site-1]*pre[site-1] + temp*pre[site] + num%pre[site];
        return num;
    }
    
    inline int Swap(int num,int site,int m)
    {
        int t1 = (num/pre[site])%10;
        int t2 = (num/pre[m])%10;
    
        if(t1 == t2)
            return num;
    
        num = num/pre[site-1]*pre[site-1] + t2*pre[site] + num%pre[site];
        num = num/pre[m-1]*pre[m-1] + t1*pre[m] + num%pre[m];
        return num;
    }
    
    bool Judge(int site,int a,int b)
    {
        if((a/pre[site])%10 == (b/pre[site])%10)
            return true;
        return false;
    }
    
    int bfs(int a,int b)
    {
        memset(mark,-1,sizeof(mark));
    
        queue<Q> q;
        Q s,t;
    
        s.sta = a;
        s.fl = 0;
        s.ans = 0;
        s.site = 1;
    
        mark[s.sta][s.site][s.fl] = 0;
        q.push(s);
    
        s.sta = b;
        s.ans = 0;
        s.fl = 1;
    
        for(int i = 1;i <= 6; ++i)
        {
            s.site = i;
            mark[s.sta][s.site][s.fl] = 0;
            q.push(s);
        }
    
        while(q.empty() == false)
        {
            t = q.front();
            q.pop();
    
           // printf("site = %2d sta = %6d fl = %2d ans = %2d
    ",t.site,t.sta,t.fl,t.ans);
    
            if(mark[t.sta][t.site][t.fl^1] != -1)
            {
                return mark[t.sta][t.site][t.fl^1] + t.ans;
            }
    
            s.fl = t.fl;
            s.ans = t.ans+1;
    
            //left
            s.sta = t.sta;
    
            if(t.site > 1 && (t.site < 2 || t.site > 5 || Judge(t.site,t.sta,t.fl == 0 ?

    b : a))) { s.site = t.site-1; if(mark[s.sta][s.site][s.fl] == -1) { mark[s.sta][s.site][s.fl] = s.ans; q.push(s); } } //right if(t.site < 6 && (t.site < 2 || t.site > 5 || Judge(t.site,t.sta,t.fl == 0 ? b : a))) { s.site = t.site+1; if(mark[s.sta][s.site][s.fl] == -1) { mark[s.sta][s.site][s.fl] = s.ans; q.push(s); } } //up s.sta = Cal(t.sta,t.site,1); s.site = t.site; if(mark[s.sta][s.site][s.fl] == -1) { mark[s.sta][s.site][s.fl] = s.ans; q.push(s); } //down s.sta = Cal(t.sta,t.site,-1); if(mark[s.sta][s.site][s.fl] == -1) { mark[s.sta][s.site][s.fl] = s.ans; q.push(s); } //swap0 if(t.site != 1) { s.sta = Swap(t.sta,t.site,1); if(mark[s.sta][s.site][s.fl] == -1) { mark[s.sta][s.site][s.fl] = s.ans; q.push(s); } } //swap1 if(t.site != 6) { s.sta = Swap(t.sta,t.site,6); if(mark[s.sta][s.site][s.fl] == -1) { mark[s.sta][s.site][s.fl] = s.ans; q.push(s); } } } return 0; } int main() { //freopen("data.txt","r",stdin); int a,b; scanf("%d %d",&a,&b); printf("%d ",bfs(a,b)); return 0; }


  • 相关阅读:
    [Graph]Doubling Algorithm
    Luogu 3203 BZOJ 2002——弹飞绵羊
    BZOJ 1468——tree
    BZOJ 10628 Luogu 2633
    Mo's Algorithm
    bzoj1063: [Noi2008]道路设计
    bzoj1264: [AHOI2006]基因匹配Match
    bzoj1177: [Apio2009]Oil
    bzoj1260: [CQOI2007]涂色paint
    bzoj3674: 可持久化并查集加强版
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5067700.html
Copyright © 2020-2023  润新知