题目描述

给定一个r行c列的在电视上的“虚拟键盘”,通过“上,下,左,右,选择”共5个控制键,你可以移动电视屏幕上的光标来打印文本。一开始,光标在键盘的左上角,每次按方向键,光标总是跳到下一个在该方向上与当前位置不同的字符,若不存在则不移动。每次按选择键,则将光标所在位置的字符打印出来。
现在求打印给定文本(要在结尾打印换行符)的最少按键次数。

输入

第一行输入 r,c。
接下来给出一个 r×c的键盘,包括大写字母,数字,横线以及星号(星号代表 Enter 换行)。
最后一行是要打印的文本串 S,S 的长度不超过 10000。

输出

输出打印文本(包括结尾换行符)的最少按键次数。保证一定有解。

样例输入

2 19
ABCDEFGHIJKLMNOPQZY
X*****************Y
AZAZ

样例输出

19

提示

对于100%的数据,1≤r,c≤50,S的长度不超过10000。



【题解】

这个题目需要大家耐心处理细节,预处理所有点的四个方向能到达的地方。

然后用BFS搜索,注意搜索的顺序,已经利用好vis标记数组来记录。

这个题目是真的需要小心,很多坑。

需要设定一个结构体,这个结构体需要提供记录  当前的坐标(x,y),匹配到下标 step,当前结点的花费的操作次数 dis

1、预处理所有位置的四个方向的下一个位置是什么?

2、设置标准的BFS框架,其中入队列之前,可以预处理左上角就是目标串的字符。

3、进入BFS框架时需要两部分,一个是选择,另一个是四个方向遍历,充分要利用vis数组来更新最优值

 #pragma GCC optimize("Ofast") //编译环境优化
#include<bits/stdc++.h>
using namespace std;
const int N = ;
const int M = 1e5+;
const int P = ;
char s[M];
int n,m,len;
int Map[P],vis[N][N];
int a[N][N],b[M];
typedef struct Node{
int x,y,step,dis;
}Node ;
Node F[N][N][]; int dir[][]={
{-,},
{,-},{,},
{,}
};
void read_Char(char s[]){
int len = ;
char c = getchar() ;
while ( c!='\n' ){
s[len++] = c;
c = getchar();
}
s[len] = '\0';
}
void _Map(){
for(int i=;i<=;i++){
Map[char(''+i)] = i+;
}
for (int i=;i<;i++){
Map[char('A'+i)] = i+;
}
Map['-'] = ;
Map['*'] = ;
}
//预处理,处理每一个方向能到达的位置
void Init(){
for(register int i=;i<=n;i++){
for(register int j=;j<=m;j++){
for(register int k=;k<;k++){
int tx = i,ty = j ;
while( a[i][j] == a[tx+dir[k][]][ty+dir[k][]] )
tx += dir[k][] , ty += dir[k][];
F[i][j][k] = (Node) {tx,ty,,};
}
}
}
}
int BFS(){ memset(vis,,sizeof(vis));
int k = ;
//处理左上角就是目标的输出
while ( a[][] == b[k] && k<=len ) k++ ;
queue <Node> Q;
Q.push( (Node){,,k,k-} ) ;
vis[][] = k ;
while( !Q.empty() ){ Node cur = Q.front();
//printf("(%d,%d)\n",cur.x,cur.y);
Q.pop();
//如果找到合适的位置则"选择"
if( a[cur.x][cur.y] == b[cur.step] ){
if( cur.step == len ){
return cur.dis + ;
}
vis[cur.x][cur.y] = cur.step + ;
Q.push( (Node) { cur.x,cur.y,cur.step+,cur.dis+} ) ;
continue ;
}
//四个方向
for(int i=;i<;i++){
Node Next = F[cur.x][cur.y][i] ;
Next.x += dir[i][];
Next.y += dir[i][]; if( !(<=Next.x && Next.x<=n && <=Next.y && Next.y<=m) ){
continue;
}
//if( a[cur.x][cur.y] == a[Next.x][Next.y] ) continue;
// 如果后面剪枝过的
if( vis[Next.x][Next.y] >= cur.step ) continue ;
vis[Next.x][Next.y] = cur.step ;
Q.push((Node){Next.x,Next.y,cur.step,cur.dis+} );
}
}
}
int main()
{
_Map();
//while( cin >> n >> m ){
while(~scanf("%d%d",&n,&m)){
//memset(a,'\0',sizeof(a));
for(register int i=;i<=n;i++){
scanf("%s",s+);
//cin >> s+1 ;
for(register int j=;j<=m;j++){
a[i][j] = Map[s[j]];
}
}
scanf("%s",s+);
//cin >> s+1 ;
len = strlen(s+);
for(register int i=;i<=len;i++){
b[i] = Map[s[i]];
}
b[++len] = Map['*'];
Init();
printf("%d\n",BFS());
//cout << BFS() << endl;
}
return ;
}
/*
2 19
ABCDEFGHIJKLMNOPQZY
X*****************Y
AZAZ
*/

Keyboarding

【广搜】Keyboarding的更多相关文章

  1. HDU--杭电--1195--Open the Lock--深搜--都用双向广搜,弱爆了,看题了没?语文没过关吧?暴力深搜难道我会害羞?

    这个题我看了,都是推荐的神马双向广搜,难道这个深搜你们都木有发现?还是特意留个机会给我装逼? Open the Lock Time Limit: 2000/1000 MS (Java/Others)  ...

  2. HDU 5652(二分+广搜)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/128683#problem/E 题目大意:给定一只含有0和1的地图,0代表可以走的格子,1代表不能走的格 子.之 ...

  3. nyoj 613 免费馅饼 广搜

    免费馅饼 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼.说来gameboy ...

  4. poj 3984:迷宫问题(广搜,入门题)

    迷宫问题 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7635   Accepted: 4474 Description ...

  5. poj 3278:Catch That Cow(简单一维广搜)

    Catch That Cow Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 45648   Accepted: 14310 ...

  6. 双向广搜 POJ 3126 Prime Path

      POJ 3126  Prime Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16204   Accepted ...

  7. 广搜+打表 POJ 1426 Find The Multiple

    POJ 1426   Find The Multiple Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 25734   Ac ...

  8. 双向广搜 codevs 3060 抓住那头奶牛

    codevs 3060 抓住那头奶牛 USACO  时间限制: 1 s  空间限制: 16000 KB  题目等级 : 黄金 Gold   题目描述 Description 农夫约翰被告知一头逃跑奶牛 ...

  9. 双向广搜+hash+康托展开 codevs 1225 八数码难题

    codevs 1225 八数码难题  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description Yours和zero在研究A*启 ...

  10. UVa12726 one Friend at a Time (位 广搜)

    题目链接:UVa12726 是个PDF,不好复制进来. 大意:有个人要追个妹子,想加妹子QQ,但是不知道谁规定的,玩QQ的人要加好友必须先要有至少k个共同好友.共有N个人玩QQ,编号为1到N,1是男主 ...

随机推荐

  1. Echarts-复杂关系图(源码)

    关系图: 代码: <!DOCTYPE html> <head> <meta charset="utf-8"> <script type=& ...

  2. slax linux的定制

    由于数据结构教学的需要,需要用到linux,要求就是小,启动快,可定制性强,恰好slax正好满足要求,以下就是定制slax linux的过程记录: 什么是Slax Slax是一个基于Linux的Liv ...

  3. Golang switch语句总结

    switch 语句基本结构 switch 条件表达式 { case 常量表达式1: 语句 1 case 常量表达式2: 语句 2 . . . case 常量表达式n: 语句 n default: 语句 ...

  4. Python——装饰器(Decorator)

    1.什么是装饰器? 装饰器放在一个函数开始定义的地方,它就像一顶帽子一样戴在这个函数的头上.和这个函数绑定在一起.在我们调用这个函数的时候,第一件事并不是执行这个函数,而是将这个函数做为参数传入它头顶 ...

  5. JavaScript作用域与闭包总结

    1.全局作用域 所有浏览器都支持 window 对象,它表示浏览器窗口,JavaScript 全局对象.函数以及变量均自动成为 window 对象的成员.所以,全局变量是 window 对象的属性,全 ...

  6. 会声会影x7 每次安装均会提示:已安装这个产品的另一个版本

    会声会影x7 每次安装均会提示:已安装这个产品的另一个版本 卸载C++2008 的库就行了 文章来源:刘俊涛的博客 欢迎关注,有问题一起学习欢迎留言.评论

  7. Linux 之Shell for循环

    @代表所有参数所以如果后面跟上echo $v你会发现他会一次显示user userdebug eng $poo -le ${#prodlist[@]} 这句话是说 $poo小于等于prodlist中的 ...

  8. ExtractIcon function Retrieves a handle to an icon from the specified executable file, DLL, or icon file.

    https://msdn.microsoft.com/zh-cn/vstudio/ms648068(v=vs.90)

  9. Antecedent Membership Functions相关资料

    属于模糊控制领域 前件隶属函数(Antecedent Membership Functions) 基于模糊近似的强化学习方法研究 - 豆丁网 https://www.docin.com/p-13022 ...

  10. Visual Studio2013的C语言编译器对C99标准的支持情况

    Visual Studio2013终于开始比较良好地支持C99特性了.在此之前,如果用C语言写代码的话,变量名都需要放到函数体的前面部分,代码写起来十分别扭. 而Visual Studio2013中的 ...