题目链接: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[][N];
int a0[], b0[], A, B;
struct node
{
int k;///光标所在位置
int num;
int step;
}; void FenNum(int n, int a[])///把n的每位数字存到a数组中;
{
int i=;
while(i)
{
a[i--]=n%;
n/=;
}
} node Op(int a[], int op, node p)
{
if(op==)
swap(a[p.k], a[]);
if(op==)
swap(a[p.k], a[]);
if(op== && a[p.k]!=)
a[p.k]++;
if(op== && a[p.k]!=)
a[p.k]--;
if(op== && p.k!=)
p.k--;
if(op== && p.k!=)
p.k++;
p.num=;
for(int i=; i<=; i++)
p.num = p.num*+a[i];
return p;
}
int bfs(int num)
{
node p;
queue<node>Q;
p.k=;
p.num = num;
p.step = ;
Q.push(p);
memset(vis, , sizeof(vis));
vis[p.k][p.num] = ;
while(Q.size())
{
p=Q.front();
Q.pop();
if(p.num==B)
return p.step; for(int i=; i<; i++)
{
FenNum(p.num, a0);
if((i==||i==) && p.k<= && p.k>= && a0[p.k]!=b0[p.k])
continue;
node pn = Op(a0, i, p);
if(vis[pn.k][pn.num]==)
{
pn.step=p.step+;
Q.push(pn);
vis[pn.k][pn.num] = ;
}
}
}
return -;
}
int main()
{
scanf("%d%d", &A, &B);
FenNum(B, b0);
int ans = bfs(A);
printf("%d\n", ans);
}

双搜:(我只看了看)

#include<stdio.h>
#include<queue>
#include<algorithm>
using namespace std; const int MAXN = 1e6; char used[MAXN][][]; struct node
{
int pass[];///保存密码
int cursor;///光标所在位置
int op;///op等于0表示从原始密码开始,等于1表示从目标密码开始
int step;///步数
}; int TurnNum(node s)
{
int sum=; for(int i=; i<; i++)
sum = sum* + s.pass[i]; return sum;
}
void TurnStr(node &s, int M)
{
for(int i=; i>; i--)
{
s.pass[i] = M % ;
M /= ;
}
}
int BFS(node s, node e)
{
queue<node> Q;
Q.push(s);
int k = TurnNum(s);
used[k][][] = true;
k = TurnNum(e);
for(int i=; i<; i++)
{
e.cursor = i;
used[k][][i] = true;
Q.push(e);
} int p[][]; for(int i=; i<=; i++)
{///保存一下原始密码,和目标密码
p[][i] = s.pass[i];
p[][i] = e.pass[i];
} while(Q.size())
{
s = Q.front();
Q.pop(); for(int i=; i<=; i++)
{
e = s; if(i == )
swap(e.pass[e.cursor], e.pass[]);
else if(i == )
swap(e.pass[e.cursor], e.pass[]);
else if(i == && e.pass[e.cursor] != )
e.pass[e.cursor] += ;
else if(i == && e.pass[e.cursor] != )
e.pass[e.cursor] -= ;
else if(i == && ( (e.cursor>= && e.cursor<= && e.pass[e.cursor]==p[e.op^][e.cursor]) || e.cursor==) )
e.cursor -= ;
else if(i == && ( (e.cursor>= && e.cursor<= && e.pass[e.cursor]==p[e.op^][e.cursor]) || e.cursor==) )
e.cursor += ; k = TurnNum(e); if(used[k][e.op][e.cursor] == )
{
if(used[k][e.op^][e.cursor])
{
return used[k][e.op^][e.cursor] + e.step-;
} e.step += ;
used[k][e.op][e.cursor] = e.step;
Q.push(e);
}
}
} return -;
} int main()
{
int S, E;
node s, e; scanf("%d%d", &S, &E); if(S == E)
{
printf("%d\n", );
return ;
} TurnStr(s, S);
TurnStr(e, E);
s.cursor = , s.op = , s.step = ;
e.op = , e.step = ; int ans = BFS(s, e); printf("%d\n", ans); return ;
}

聪明的打字员---poj1184(bfs)的更多相关文章

  1. poj1184 聪明的打字员(BFS剪枝)

    http://poj.org/problem?id=1184 用字符串s存下数字,并把光标位置做一个字符加到s末尾,用map做标记状态是否出现过,然后bfs即可. 不剪枝是过不了的,考虑的两种交换操作 ...

  2. codevs 1733 聪明的打字员 (Bfs)

    /* Bfs+Hash 跑的有点慢 但是codevs上时间限制10s 也ok */ #include<iostream> #include<cstdio> #include&l ...

  3. POJ 1184 聪明的打字员

    简直难到没朋友. 双向bfs + 剪枝. 剪枝策略: 对于2--5位置上的数,仅仅有当光标在相应位置时通过swap ,up.down来改变.那么当当前位置没有达到目标状态时,left和right无意义 ...

  4. (广搜)聪明的打字员 -- POJ --1184

    链接: http://poj.org/problem?id=1184 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=88230#probl ...

  5. poj练习题的方法

    poj1010--邮票问题 DFSpoj1011--Sticks dfs + 剪枝poj1020--拼蛋糕poj1054--The Troublesome Frogpoj1062--昂贵的聘礼poj1 ...

  6. 06day2

    蠕虫游戏 模拟 [问题描述] 蠕虫是一个古老的电脑游戏,它有许多版本.但所有版本都有一个共同规则:操纵一条蠕虫在屏幕上转圈,并试着去避免撞到自己或障碍物. 这里我们将模拟一个简单的版本.游戏将在 50 ...

  7. codevs 3290 华容道(SPFA+bfs)

    codevs 3290华容道 3290 华容道 2013年NOIP全国联赛提高组 时间限制: 1 s  空间限制: 128000 KB 题目描述 Description 小 B 最近迷上了华容道,可是 ...

  8. AC日记——逃出克隆岛 (bfs)

    2059 逃出克隆岛  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description oi小组的yh酷爱玩魔兽rpg,每天都 ...

  9. acdream 1681 跳远女王(BFS,暴力)

    Problem Description 娜娜觉得钢琴很无趣了,就抛弃了钢琴,继续往前走,前面是一片湖,娜娜想到湖的对岸,可惜娜娜找了好久都没找到小桥和小船,娜娜也发现自己不是神仙,不能像八仙过海一样. ...

随机推荐

  1. JQuery为元素添加样式的实现方法

    由于jquery支持css3,所有能很好的兼容很多浏览器,所以通过jquery来使用css样式比较好 为定义好的css样式可以调用元素的css方法添加样式 $("span").cs ...

  2. MathType编辑半直积符号的步骤

    在数学中,特别是叫做群论的抽象代数领域中,半直积(semidirect product)是从其中一个是正规子群的两个子群形成一个群的特定方法.半直积是直积的推广.半直积是作为集合的笛卡尔积,但带有特定 ...

  3. ChemDraw教程:如何查看和删除俗名

    化学范畴里,允许用俗名表示ChemDraw原子标记或原子标记的一部分,可以定义俗名的快捷键也可以自由查看或删除俗名,熟练掌握可以提高ChemDraw软件使用效率,下面将具体介绍此部分内容. 一.查看俗 ...

  4. python--list和tuple类型--2

    原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuewei/ 一.创建list Python内置的一种数据类型是列表:list.list是一种有序的集合,可以 ...

  5. cocos2d 中使用jni C++ 调用 Java 方法

    1.简单数据类型样例 如果我们Java中有这么一个open的静态方法,它没有參数,有一个int的返回值.怎么在C++中调用它呢? package cb.CbCCBLE; public class Cb ...

  6. mybatis由浅入深day02_4多对多查询_多对多查询总结

    4 多对多查询 4.1 需求(查询用户及用户购买商品信息) 查询用户及用户购买商品信息. 4.2 sql语句 查询主表是:用户表 关联表:由于用户和商品没有直接关联,通过订单和订单明细进行关联,所以关 ...

  7. HTML的框架结构

    <html> <head> <title>HTML的框架结构</title> </head> <frameset frameborde ...

  8. 高级类特性----抽象类(abstract class)

    抽象类(abstract class) 随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用.类的设计应该保证父类和子类能够共享特征.有时将一个父类设计得非常抽象,以至于它没有具 ...

  9. Python 爬虫知识点 - XPath

    http://cuiqingcai.com/2621.html 一.基础介绍 <bookstore> <book> <title>Harry Potter</ ...

  10. python常用内置模块,执行系统命令的模块

    Subprocess模块 python3.5将使用Subprocess模块跟操作系统进行交互,比如系统命令,他将替换 os.system os.spawn* subprocess.run()方法封装的 ...