聪明的打字员---poj1184(bfs)
题目链接: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)的更多相关文章
- poj1184 聪明的打字员(BFS剪枝)
http://poj.org/problem?id=1184 用字符串s存下数字,并把光标位置做一个字符加到s末尾,用map做标记状态是否出现过,然后bfs即可. 不剪枝是过不了的,考虑的两种交换操作 ...
- codevs 1733 聪明的打字员 (Bfs)
/* Bfs+Hash 跑的有点慢 但是codevs上时间限制10s 也ok */ #include<iostream> #include<cstdio> #include&l ...
- POJ 1184 聪明的打字员
简直难到没朋友. 双向bfs + 剪枝. 剪枝策略: 对于2--5位置上的数,仅仅有当光标在相应位置时通过swap ,up.down来改变.那么当当前位置没有达到目标状态时,left和right无意义 ...
- (广搜)聪明的打字员 -- POJ --1184
链接: http://poj.org/problem?id=1184 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=88230#probl ...
- poj练习题的方法
poj1010--邮票问题 DFSpoj1011--Sticks dfs + 剪枝poj1020--拼蛋糕poj1054--The Troublesome Frogpoj1062--昂贵的聘礼poj1 ...
- 06day2
蠕虫游戏 模拟 [问题描述] 蠕虫是一个古老的电脑游戏,它有许多版本.但所有版本都有一个共同规则:操纵一条蠕虫在屏幕上转圈,并试着去避免撞到自己或障碍物. 这里我们将模拟一个简单的版本.游戏将在 50 ...
- codevs 3290 华容道(SPFA+bfs)
codevs 3290华容道 3290 华容道 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 小 B 最近迷上了华容道,可是 ...
- AC日记——逃出克隆岛 (bfs)
2059 逃出克隆岛 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description oi小组的yh酷爱玩魔兽rpg,每天都 ...
- acdream 1681 跳远女王(BFS,暴力)
Problem Description 娜娜觉得钢琴很无趣了,就抛弃了钢琴,继续往前走,前面是一片湖,娜娜想到湖的对岸,可惜娜娜找了好久都没找到小桥和小船,娜娜也发现自己不是神仙,不能像八仙过海一样. ...
随机推荐
- sql字符串的拼接 (字符串和二进制,erlang的mysql驱动)
1> list_to_binary(["select * from aa limit","1",",","97"] ...
- winform程序_根据输入的sql生成excel(字段名与sql一致)
自己打开看吧 app.config可配置数据库路径 excel保存路径.... 源码下载链接: http://pan.baidu.com/s/1bnHPhdd
- 下次不用找了,all language code
语言 ID 语言 ID 决定网站中网页文本(例如“网站设置”页上的文本)使用的语言.创建网站时可用的语言取决于在服务器或服务器场中安装的语言模板包.基于 Windows SharePoint Serv ...
- linux下 redis 启动
启动文件 startredis.sh : nohup /data/redis/bin/redis-server /data/redis/etc/redis.conf & 关闭文件 stopr ...
- Post方式调用wcf服务
我们平常在PC端调用WCF服务,只要知道WCF服务的地址,客户端直接添加引用服务就可以使用了,殊不知还有其他方式,其实,我们也可以 通过HTTP POST的方式调用WCF服务,这样就不用添加引用了,在 ...
- vertical-align负值和margin-bottom负值的区别
先看一下vertical-align在W3C当中的值有哪一些: 可是它有数值这一说确实很少提起,我们来看这么一段代码: <!DOCTYPE html> <html lang=&quo ...
- php上传文件中文文件名乱码的解决方法
文件上传是我们在处理表单提交时候最常用的功能之一,今天写了一个小小的demo,如下: 先看结构: html为表单提交的页面,php为处理表单的文件,upload为上传文件所放的位置 html: < ...
- 《C++ Primer Plus》第13章 类继承 笔记
类继承通过使用已有的类(基类)定义新的来(派生类),使得能够根据需要修改编程代码.共有继承建立is-a关系,这意味着派生类对象也应该是某种基类对象.作为is-a模型的一部分,派生类继承基类的数据称源和 ...
- (三)微信小程序之发送服务通知(模板消息)
1.后端获取AccessToken返回给微信端 微信小程序端请求后端得到AccessToken 2.后端获取openid返回给微信端 微信小程序端登录请求后端得到openid 3.发送消息 ...
- 使用Sublime Text 3做Python开发
引言 刚转到OS X平台时,寻找写Python,JavaScript,Markdown等文件的工具时,比较了许多工具, 最终选择了Sublime Text 2,主要原因是其跨平台, 想着以后再转到wi ...