聪明的打字员---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 娜娜觉得钢琴很无趣了,就抛弃了钢琴,继续往前走,前面是一片湖,娜娜想到湖的对岸,可惜娜娜找了好久都没找到小桥和小船,娜娜也发现自己不是神仙,不能像八仙过海一样. ...
随机推荐
- BWT转换对字符串进行编码
今天看了下bowtie 的论文, 里面描述了BWT转换的过程和bowtie的比对算法: NGS测序数据的数据量非常大, 为了更快的处理, 通常需要对数据进行压缩:而BWT实际上就是一种数据转换方法, ...
- vncserver的安装和使用
环境:RedHat Linux 6企业版.Xwindows:gnome (红帽默认安装的图形界面) 尽管我们可以使用SSH连接远程通过字符界面来操作Linux,但是对于更多熟悉图形人来说是很不方便的, ...
- 【Java面试题】51 什么时候用assert。
assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制. 在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保 ...
- 算法--将Excel列索引转换成默认标识
使用POI导入Excel时,有时对模板进行验证,假如第1行第1列错误,此时的rowIndex=columnIndex=0,与平时看到的Excel行列标记相比不太直观,因此通过相应的算法将其转换成人们熟 ...
- 制作一款3D炸弹超人游戏
说起炸弹超人,相信很多朋友都玩过类似的游戏,其中最为人熟知的莫过于<泡泡堂>.该类型游戏需要玩家在地图中一边跑动一边放置炸弹,同时还要躲避敌方炸弹保护自己.最初的炸弹超人游戏都是2D的,今 ...
- ASP.Net MVC开发基础学习笔记(7):数据查询页面
前言 前面铺垫了那么多,今天我们就用MVC5 + EF6 + Bootstrap3来正式创建一个基本查询页面. 为什么从查询页面開始?嘿嘿.由于小弟的.Net生涯就是从查询页面開始的,记得正式工 ...
- 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 ...
- JavaScript中eval()函数
eval调用时,实例为eval( "( javascript代码 )" ), eval() 函数可将字符串转换为代码执行,并返回一个或多个值.
- 【Thinkphp5】结合layer弹窗 定制操作结果页面
1 打开应用公共文件页面 appliction/common.php,编写以下代码 注意: 成功消息的绿色背景部分是iframe 框架写法,如果是普通页面.就吧parent去除,改为: self ...
- Android长截屏-- ScrollView,ListView及RecyclerView截屏
http://blog.csdn.net/wbwjx/article/details/46674157 Android长截屏-- ScrollView,ListView及RecyclerV ...