列表

详情


NC50267. Keyboarding

描述

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

输入描述

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

输出描述

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

示例1

输入:

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

输出:

19

示例2

输入:

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

输出:

160

示例3

输入:

6 4
AXYB
BBBB
KLMB
OPQB
DEFB
GHI*
AB

输出:

7

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 668ms, 内存消耗: 632K, 提交时间: 2022-09-23 21:30:57

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
typedef pair<int,int>PII;
typedef long long ll;
const int N=60;
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
struct node{
 int x,y,dis,stp;
}t;
int len;
int r,c;
int v[N][N];
PII ne[N][N][5];
char mp[N][N],s[10001];
int bfs()
{
    queue<node> q;
    q.push({1,1,0,0});
    while(q.size())
    {
        auto t=q.front();
        q.pop();
        if(mp[t.x][t.y]==s[t.stp])
        {
            if(t.stp==len)
            {
                return t.dis+1;
            }
            t.stp++;
            t.dis++;
            v[t.x][t.y]=t.stp;
            q.push(t);
            continue;
        }
        for(int i=0;i<4;i++)
        {
            int x=ne[t.x][t.y][i].first;
            int y=ne[t.x][t.y][i].second;
            if(v[x][y]<t.stp)
            {
                v[x][y]=t.stp;
                q.push({x,y,t.dis+1,t.stp});
            }
        }
    }
    return 0;
}
int  main()
{
    memset(v,-1,sizeof v);
    cin>>r>>c;
    for(int i=1;i<=r;i++)
        for(int j=1;j<=c;j++)
        cin>>mp[i][j];
    cin>>s;
    len =strlen(s);

    s[len]='*';
    for(int i=1;i<=r;i++)
        for(int j=1;j<=c;j++)
    {
        for(int k=0;k<4;k++)
        {
            int x=i+dx[k];
            int y=j+dy[k];
            while(mp[i][j]==mp[x][y])
                x+=dx[k],y+=dy[k];
            if(x<=0||x>r||y<=0||y>c)
            {
                ne[i][j][k]={i,j};
            }else
            {
                ne[i][j][k]={x,y};
            }
        }
    }
    cout<<bfs();


    return 0;
}

C++ 解法, 执行用时: 1151ms, 内存消耗: 25040K, 提交时间: 2022-04-02 22:22:09

#include<bits/stdc++.h>
using namespace std;
const int dx[4] = {0,1,0,-1},dy[4] = {1,0,-1,0};
struct node{
	int x,y,step,index;
}t;
int r,c,Next[51][51][4][2];
bool v[51][51][10001];
char s[10002],key[51][51];
queue <node> q;
int main(){
	cin>>r>>c;
	int len,x,y,i,j,k;
	for (i = 0;i < r;i++)
		cin>>key[i];
	cin>>s;
	len = strlen(s);
	s[len] = '*';
	for (i = 0;i < r;i++)
		for (j = 0;j < c;j++)
			for (k = 0;k < 4;k++){
				x = i;
				y = j;
				while (key[x][y] == key[i][j]){
					x += dx[k];
					y += dy[k];
				}
				Next[i][j][k][0] = x;
				Next[i][j][k][1] = y;
			}
	t.x = 0;
	t.y = 0;
	t.step = 0;
	t.index = 0;
	q.push(t);
	v[0][0][0] = 1;
	while (!q.empty()){
		t = q.front();
		q.pop();
		if (key[t.x][t.y] == s[t.index]){
			if (t.index == len)break;
			t.step++;
			t.index++;
			q.push(t);
			v[t.x][t.y][t.index] = 1;
			continue;
		}
		for (i = 0;i < 4;i++){
			x = Next[t.x][t.y][i][0];
			y = Next[t.x][t.y][i][1];
			if (0 <= x && x < r && 0 <= y && y < c && !v[x][y][t.index]){
				q.push((node){x,y,t.step + 1,t.index}) ;
				v[x][y][t.index] = 1;
			}
		}
	}
	cout<<t.step + 1;
	return 0;
}

上一题