码迷,mamicode.com
首页 > 其他好文 > 详细

聪明的打字员---poj1184(bfs)

时间:2015-08-19 10:43:03      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:http://poj.org/problem?id=1184

分析:首先可以发现有6*10^6种状态,比较多,不过搜索的时候可以去除一些无用的状态,

可以发现一个点的值(2-5)如果想要改变那么光标必须在该点处,

所以当光标在2-5位置时候,必须要要把值变为与目标位置处一样才可以移动。

 

单搜:

技术分享
#include<stdio.h>
#include<queue>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 1000002
int vis[7][N];
int a0[10], b0[10], A, B;
struct node
{
    int k;///光标所在位置
    int num;
    int step;
};

void FenNum(int n, int a[])///把n的每位数字存到a数组中;
{
    int i=6;
    while(i)
    {
        a[i--]=n%10;
        n/=10;
    }
}

node Op(int a[], int op, node p)
{
    if(op==0)
        swap(a[p.k], a[1]);
    if(op==1)
        swap(a[p.k], a[6]);
    if(op==2 && a[p.k]!=9)
        a[p.k]++;
    if(op==3 && a[p.k]!=0)
        a[p.k]--;
    if(op==4 && p.k!=1)
        p.k--;
    if(op==5 && p.k!=6)
        p.k++;
    p.num=0;
    for(int i=1; i<=6; i++)
        p.num = p.num*10+a[i];
    return p;
}
int bfs(int num)
{
    node p;
    queue<node>Q;
    p.k=1;
    p.num = num;
    p.step = 0;
    Q.push(p);
    memset(vis, 0, sizeof(vis));
    vis[p.k][p.num] = 1;
    while(Q.size())
    {
        p=Q.front();
        Q.pop();
        if(p.num==B)
            return p.step;

        for(int i=0; i<6; i++)
        {
            FenNum(p.num, a0);
            if((i==4||i==5) && p.k<=5 && p.k>=2 &&  a0[p.k]!=b0[p.k])
                continue;
            node pn = Op(a0, i, p);
            if(vis[pn.k][pn.num]==0)
            {
                pn.step=p.step+1;
                Q.push(pn);
                vis[pn.k][pn.num] = 1;
            }
        }
    }
    return -1;
}
int main()
{
    scanf("%d%d", &A, &B);
    FenNum(B, b0);
    int ans = bfs(A);
    printf("%d\n", ans);
}
View Code

双搜:(我只看了看)

技术分享
#include<stdio.h>
#include<queue>
#include<algorithm>
using namespace std;

const int MAXN = 1e6;

char used[MAXN][2][7];

struct node
{
    int pass[7];///保存密码
    int cursor;///光标所在位置
    int op;///op等于0表示从原始密码开始,等于1表示从目标密码开始
    int step;///步数
};

int TurnNum(node s)
{
    int sum=0;

    for(int i=1; i<7; i++)
        sum = sum*10 + s.pass[i];

    return sum;
}
void TurnStr(node &s, int M)
{
    for(int i=6; i>0; i--)
    {
        s.pass[i] = M % 10;
        M /= 10;
    }
}
int BFS(node s, node e)
{
    queue<node> Q;
    Q.push(s);
    int k = TurnNum(s);
    used[k][0][1] = true;
    k = TurnNum(e);
    for(int i=1; i<7; i++)
    {
        e.cursor = i;
        used[k][1][i] = true;
        Q.push(e);
    }

    int p[2][7];

    for(int i=1; i<=6; i++)
    {///保存一下原始密码,和目标密码
        p[0][i] = s.pass[i];
        p[1][i] = e.pass[i];
    }

    while(Q.size())
    {
        s = Q.front();
        Q.pop();

        for(int i=1; i<=6; i++)
        {
            e = s;

            if(i == 1)
                swap(e.pass[e.cursor], e.pass[1]);
            else if(i == 2)
                swap(e.pass[e.cursor], e.pass[6]);
            else if(i == 3 && e.pass[e.cursor] != 9)
                e.pass[e.cursor] += 1;
            else if(i == 4 && e.pass[e.cursor] != 0)
                e.pass[e.cursor] -= 1;
            else if(i == 5 && ( (e.cursor>=2 && e.cursor<=5 && e.pass[e.cursor]==p[e.op^1][e.cursor]) || e.cursor==6) )
                e.cursor -= 1;
            else if(i == 6 && ( (e.cursor>=2 && e.cursor<=5 && e.pass[e.cursor]==p[e.op^1][e.cursor]) || e.cursor==1) )
                e.cursor += 1;

            k = TurnNum(e);

            if(used[k][e.op][e.cursor] == 0)
            {
                if(used[k][e.op^1][e.cursor])
                {
                    return used[k][e.op^1][e.cursor] + e.step-1;
                }

                e.step += 1;
                used[k][e.op][e.cursor] = e.step;
                Q.push(e);
            }
        }
    }

    return -1;
}

int main()
{
    int S, E;
    node s, e;

    scanf("%d%d", &S, &E);


    if(S == E)
    {
        printf("%d\n", 0);
        return 0;
    }

    TurnStr(s, S);
    TurnStr(e, E);
    s.cursor = 1, s.op = 0, s.step = 1;
    e.op = 1, e.step = 1;

    int ans = BFS(s, e);

    printf("%d\n", ans);

    return 0;
}
View Code

 

聪明的打字员---poj1184(bfs)

标签:

原文地址:http://www.cnblogs.com/zhengguiping--9876/p/4741476.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!