题目链接: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. BWT转换对字符串进行编码

    今天看了下bowtie 的论文, 里面描述了BWT转换的过程和bowtie的比对算法: NGS测序数据的数据量非常大, 为了更快的处理, 通常需要对数据进行压缩:而BWT实际上就是一种数据转换方法, ...

  2. vncserver的安装和使用

    环境:RedHat Linux 6企业版.Xwindows:gnome (红帽默认安装的图形界面) 尽管我们可以使用SSH连接远程通过字符界面来操作Linux,但是对于更多熟悉图形人来说是很不方便的, ...

  3. 【Java面试题】51 什么时候用assert。

    assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制. 在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保 ...

  4. 算法--将Excel列索引转换成默认标识

    使用POI导入Excel时,有时对模板进行验证,假如第1行第1列错误,此时的rowIndex=columnIndex=0,与平时看到的Excel行列标记相比不太直观,因此通过相应的算法将其转换成人们熟 ...

  5. 制作一款3D炸弹超人游戏

    说起炸弹超人,相信很多朋友都玩过类似的游戏,其中最为人熟知的莫过于<泡泡堂>.该类型游戏需要玩家在地图中一边跑动一边放置炸弹,同时还要躲避敌方炸弹保护自己.最初的炸弹超人游戏都是2D的,今 ...

  6. ASP.Net MVC开发基础学习笔记(7):数据查询页面

     前言 前面铺垫了那么多,今天我们就用MVC5 + EF6 + Bootstrap3来正式创建一个基本查询页面. 为什么从查询页面開始?嘿嘿.由于小弟的.Net生涯就是从查询页面開始的,记得正式工 ...

  7. leetCode 33.Search in Rotated Sorted Array(排序旋转数组的查找) 解题思路和方法

    Search in Rotated Sorted Array Suppose a sorted array is rotated at some pivot unknown to you before ...

  8. JavaScript中eval()函数

    eval调用时,实例为eval( "( javascript代码 )" ), eval() 函数可将字符串转换为代码执行,并返回一个或多个值.

  9. 【Thinkphp5】结合layer弹窗 定制操作结果页面

    1 打开应用公共文件页面    appliction/common.php,编写以下代码 注意: 成功消息的绿色背景部分是iframe 框架写法,如果是普通页面.就吧parent去除,改为: self ...

  10. Android长截屏-- ScrollView,ListView及RecyclerView截屏

    http://blog.csdn.net/wbwjx/article/details/46674157       Android长截屏-- ScrollView,ListView及RecyclerV ...