题目链接: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. 扫盲:java中关于路径的问题

    ../FileName:当前工程的上级目录. ./FileName:当前工程所在的目录. /FileName:当前工程所在磁盘的根目录(windows下). FileName:当前工程所在的目录.

  2. redis的学习使用(ubuntu系统下)

    1.安装redis,/usr/local/redis-4.0.1/src/redis-server启动服务,若想启动后自动退出redis控制台进行其他操作,可配置redis.config中  daem ...

  3. 安装 oracle [转]

    先下载3个东西:链接忘记了,大家自己找一下 1  ORA+11+G+R2+server+64bit+for+windows.iso  (Oracle 安装文件) 2  PLSql 3  oracle6 ...

  4. 演示--Jquery核心选择器

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. Unity3D协程

    协程介绍 Unity的协程系统是基于C#的一个简单而强大的接口 ,IEnumerator,它允许你为自己的集合类型编写枚举器.这一点你不必关注太多,我们直接进入一个简单的例子来看看协程到底能干什么.首 ...

  6. windows cmd中查看某个命令所在的路径

    需求描述: 之前用linux环境下的which命令就能看到某个命令的绝对路径, 然后想在windows下的cmd中是否也能够查看到命令的绝对路径呢 操作过程: 1.windows环境下,通过where ...

  7. impala不能查询hive中新增加的表问题

         使用Cloudera Manager部署安装的CDH和Impala,Hive中新增加的表,impala中查询不到,其原因是/etc/impala/conf下面没有hadoop和hive相关的 ...

  8. ZooKeeper(六)-- CAP和BASE理论、ZAB协议

    一.CAP理论和BASE理论 1.CAP理论 CAP理论,指的是在一个分布式系统中,不可能同时满足Consistency(一致性). Availability(可用性).Partition toler ...

  9. 如果我们的MCU调试不通过,我们该如何测试?(未完待续)

    我们拿到一款MCU,首先在选型的时候对他们都会有一个大概的了解,首先我们知道它多大与的FLASH,多大的RAM,是否与我们的项目适合,资源上是否足够,内频是否足够,运行速率能否达到标准,性能怎么样,比 ...

  10. UITableView划动删除的实现

    对于app应用来说,使用列表的形式展现数据非UITableView莫属.在熟练掌握了用UITableView展示数据以后,是不是也遇到了需要删除数据的需求?是不是觉得在一行数据上划动一下,然后出现一个 ...