#10030. 「一本通 1.4 练习 2」Keyboarding

news/2024/10/20 16:47:00/

[ICPC2015 WF]Keyboarding

题面翻译

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

题目描述

How many keystrokes are necessary to type a text message? You may think that it is equal to the number of characters in the text, but this is correct only if one keystroke generates one character. With pocket-size devices, the possibilities for typing text are often limited. Some devices provide only a few buttons, significantly fewer than the number of letters in the alphabet. For such devices, several strokes may be needed to type a single character. One mechanism to deal with these limitations is a virtual keyboard displayed on a screen, with a cursor that can be moved from key to key to select characters. Four arrow buttons control the movement of the cursor, and when the cursor is positioned over an appropriate key, pressing the fifth button selects the corresponding character and appends it to the end of the text. To terminate the text, the user must navigate to and select the Enter key. This provides users with an arbitrary set of characters and enables them to type text of any length with only five hardware buttons.

In this problem, you are given a virtual keyboard layout and your task is to determine the minimal number of strokes needed to type a given text, where pressing any of the five hardware buttons constitutes a stroke. The keys are arranged in a rectangular grid, such that each virtual key occupies one or more connected unit squares of the grid. The cursor starts in the upper left corner of the keyboard and moves in the four cardinal directions, in such a way that it always skips to the next unit square in that direction that belongs to a different key. If there is no such unit square, the cursor does not move.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JOTYh3Sf-1687073211325)(https://vj.z180.cn/4393d80e3f068a496c9b906fdca621d9?v=1603457188)]

Figure 1: Sample Input 1. An example virtual keyboard and hardware buttons.

Figure 1, illustrating Sample Input 1, shows a possible way to type CONTEST using 30 strokes on an example virtual keyboard. The red dots represent the virtual keys where the select button was pressed.

输入格式

The first line of the input contains two integers r r r and c c c ( 1 ≤ r , c ≤ 50 1 \leq r, c \leq 50 1r,c50), giving the number of rows and columns of the virtual keyboard grid. The virtual keyboard is specified in the next r r r lines, each of which contains c c c characters. The possible values of these characters are uppercase letters, digits, a dash, and an asterisk (representing Enter). There is only one key corresponding to any given character. Each key is made up of one or more grid squares, which will always form a connected region. The last line of the input contains the text to be typed. This text is a non-empty string of at most 10 000 10\, 000 10000 of the available characters other than the asterisk.

输出格式

Display the minimal number of strokes necessary to type the whole text, including the Enter key at the end. It is guaranteed that the text can be typed.

样例 #1

样例输入 #1

4 7
ABCDEFG
HIJKLMN
OPQRSTU
VWXYZ**
CONTEST

样例输出 #1

30

样例 #2

样例输入 #2

5 20
12233445566778899000
QQWWEERRTTYYUUIIOOPP
-AASSDDFFGGHHJJKKLL*
--ZZXXCCVVBBNNMM--**
--------------------
ACM-ICPC-WORLD-FINALS-2015

样例输出 #2

160

样例 #3

样例输入 #3

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

样例输出 #3

19

样例 #4

样例输入 #4

6 4
AXYB
BBBB
KLMB
OPQB
DEFB
GHI*
AB

样例输出 #4

7

提示

Time limit: 3000 ms, Memory limit: 1048576 kB.

International Collegiate Programming Contest (ACM-ICPC) World Finals 2015

大致思路

  • 数据范围不大,暴力BFS即可
  • BFS队列中的元素记录当前位置和当前匹配的位数
  • 但是要求下一个字符与当前位置不同,可能会有大量无用计算
  • 需要预处理出每个位置在每个方向上下一个位置
void init(){//预处理sy[0]=sy[2]=y,sx[1]=sx[3]=x;for(int i=x;i&&mi[i][y]==a;i--) sx[0]=i;sx[0]--;for(int i=x;i<=n&&mi[i][y]==a;i++) sx[2]=i;sx[2]++;for(int j=y;j<=m&&mi[x][j]==a;j++) sy[1]=j;sy[1]++;for(int j=y;j&&mi[x][j]==a;j--) sy[3]=j;sy[3]--;}

剩下的依旧是bfs模板

void bfs(){queue<node> q;q.push(node(1, 1, 0, 0));while(!q.empty()){//逐个匹配node k=q.front();q.pop();if(mp[k.a][k.b].a==s[k.t]){if(k.t==len){printf("%d\n",k.step+1);return;}vis[k.a][k.b] =k.t+1;q.push(node(k.a,k.b,k.t+1,k.step+1));continue;}for(int i=0;i<4;i++) {int dx=mp[k.a][k.b].sx[i],dy=mp[k.a][k.b].sy[i];if(dx<1||dx>n||dy<1||dy>m) continue;if(dx==k.a&&dy==k.b) continue;if(vis[dx][dy]>=k.t) continue;vis[dx][dy]=k.t;q.push(node(dx,dy,k.t,k.step+1));}}
}
  • AC CODE

#include<bits/stdc++.h>
using namespace std;
int n,m,ans,len,vis[55][55],mi[55][55];
char s[10005];
struct point{int a,x,y,sx[4],sy[4];void init(){//预处理sy[0]=sy[2]=y,sx[1]=sx[3]=x;for(int i=x;i&&mi[i][y]==a;i--) sx[0]=i;sx[0]--;for(int i=x;i<=n&&mi[i][y]==a;i++) sx[2]=i;sx[2]++;for(int j=y;j<=m&&mi[x][j]==a;j++) sy[1]=j;sy[1]++;for(int j=y;j&&mi[x][j]==a;j--) sy[3]=j;sy[3]--;}
}mp[55][55];
struct node{int a, b, t, step;node(int aa,int bb,int tt,int ss){a=aa,b=bb,t=tt,step=ss;}
};
void bfs(){queue<node> q;q.push(node(1, 1, 0, 0));while(!q.empty()){//逐个匹配node k=q.front();q.pop();if(mp[k.a][k.b].a==s[k.t]){if(k.t==len){printf("%d\n",k.step+1);return;}vis[k.a][k.b] =k.t+1;q.push(node(k.a,k.b,k.t+1,k.step+1));continue;}for(int i=0;i<4;i++) {int dx=mp[k.a][k.b].sx[i],dy=mp[k.a][k.b].sy[i];if(dx<1||dx>n||dy<1||dy>m) continue;if(dx==k.a&&dy==k.b) continue;if(vis[dx][dy]>=k.t) continue;vis[dx][dy]=k.t;q.push(node(dx,dy,k.t,k.step+1));}}
}
int main(){cin>>n>>m;for(int i=1;i<=n;i++){scanf("%s",s+1);for(int j=1;j<=m;j++){mi[i][j]=mp[i][j].a=s[j];mp[i][j].x=i,mp[i][j].y=j;vis[i][j]=-1;}}for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) mp[i][j].init();scanf("%s", s);len=strlen(s);s[len]='*';bfs();return 0;
}

http://www.ppmy.cn/news/461320.html

相关文章

Linux 下的Bluetooth 架构

文章转载自&#xff1a;http://blog.sina.com.cn/samzhen1977 实战Linux Bluetooth编程&#xff08;一&#xff09; 协议栈概述 Sam一年前在Linux下写了一个类似Windows下BTW的库--BTX。现在需要添加新功能时发现很多知识点都忘记了。所以决定在这次学习中&#xff0c;把一些bl…

人员定位系统硬件篇:蓝牙定位信标知识科普

蓝牙定位信标是一种使用电池供电&#xff0c;基于低功耗蓝牙广播协议的无线电子设备&#xff0c;是区域人员定位系统中不可或缺的一个节点。它通常固定在某个位置&#xff0c;向周围进行周期性广播&#xff0c;进而与终端设备进行信息交互&#xff0c;蓝牙定位信标具备发送“信…

Bluetooth--蓝牙开发扫描设备,及蓝牙设备类型

请先阅读: http://blog.csdn.net/angcyo/article/details/52035894 1:AndroidManifest.xml注册蓝牙扫描广播 注意蓝牙的权限. <!--蓝牙广播--> <receiverandroid:name"com.angcyo.bluetooth.BluetoothReceiver"android:exported"true"><…

Android蓝牙内核级设备驱动设计

蓝牙内核级设备驱动设计 1、Android 蓝牙架构 1)蓝牙设备驱动的位置 – 内核之中 2)协议位于内核中的有哪些 —— HCI接口实现、L2CAP、RFCOMM 3) C++ 中的是怎样通信的 —— 使用到一个接口 socket API 也就是内核的蓝牙模块给上层呈现的是网络接口的模式 ,所以上层访问…

硬件篇:教你做STM32蓝牙小车(基于STM32F103ZET6)

重要声明 看过我前面51小车博客的都知道我是软件工程专业的&#xff0c;对于硬件方面都是因为感兴趣自学的&#xff0c;这不&#xff0c;因为今年寒假放假比较早&#xff0c;趁这个时间学习了STM32相关知识&#xff0c;经过近一个月的学习对于STM32算是入门了&#xff0c;为了…

Android 蓝牙 bluetoothle 开发

前段时间项目中用到了bluetoothle 方面的开发&#xff0c;项目结束后总结一下&#xff0c;开发的流程与一些思路&#xff1b; 主要步骤 一&#xff1a;注册蓝牙所需权限 二&#xff1a;Android 6.0 以上权限获取定位权限 三&#xff1a;开启蓝牙 四&#xff1a;注册一个专门…

蓝牙开发|蓝牙技术介绍

蓝牙技术介绍 1. 蓝牙概述 蓝牙&#xff0c;是一种支持设备短距离通信&#xff08;一般10m内&#xff09;的无线电技术&#xff0c;能在包括移动电话、PDA、无线耳机、笔记本电脑、相关外设等众多设备之间进行无线信息交换。利用“蓝牙”技术&#xff0c;能够有效地简化移动通…

BLE蓝牙设备开发

&#xff08;ps. 根据网上的知识进行的学习总结&#xff09; 1、蓝牙模块概述 1.1 蓝牙模块 蓝牙&#xff0c;是一种支持设备短距离通信&#xff08;一般10m内&#xff09;的无线电技术&#xff0c;能在包括移动电话、PDA、无线耳机、笔记本电脑、相关外设等众多设备之间进行…