zoukankan      html  css  js  c++  java
  • Keyboarding

    https://loj.ac/problem/10030

    题目描述

      给出一个虚拟键盘,键盘上有一光标,可以上下左右移动,移动时沿该方向一直移动到不同字符,求将给定字符串输出的最小步数(初始位置在左上角,移动为一步,点击键盘为一步,字符串结尾有换行符,用(‘*’)表示)。

    思路

      首先每一步移动时都可能会移动多步,而数据范围又比较小,所以我们可以先预处理出从((i,j))位置出发沿四个方向所移动的步数。接下来就开始(bfs)。不过这道题的特殊之处是我们需要存储两个量,表示到((i,j))这个位置经过(step)步最多能输出多少个给定的字符。这样我们就可以用一个数组来存到((i,j))最多完成几个字符的输出,就可以减少不必要的求解。而对于目前所在的位置就是要输出的字符特殊处理一下即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    struct aa
    {
        int x,y,step,num;
        aa(int x=0,int y=0,int step=0,int num=0):x(x),y(y),step(step),num(num){}
    };
    int dx[5]={1,-1,0,0},dy[5]={0,0,1,-1};
    int v[60][60],a[60][60][5];
    char goal[10100],key[60][60];
    queue<aa> q;
    int main() 
    {
        int len,ans,r,c;
        scanf("%d%d",&r,&c);
        for(int i=1;i<=r;i++)
            scanf(" %s",key[i]+1);
        scanf(" %s",goal+1);
        goal[strlen(goal+1)+1]='*';
        len=strlen(goal+1);
        for(int i=1;i<=r;i++)
            for(int j=1;j<=c;j++)
                for(int k=0;k<4;k++)
                {
                    int nx=i,ny=j,t=0;
                    while(nx>0&&nx<=r&&ny>0&&ny<=c)
                    {
                        if(key[nx][ny]!=key[i][j])break ;
                        nx+=dx[k];ny+=dy[k];t++;
                    }
                    if(nx>0&&nx<=r&&ny>0&&ny<=c)
                        a[i][j][k]=t;                //从(i,j)沿k方向要走多少步 
                }
        v[1][1]=1;                                    //到(i,j)最多输出多少字符 
        q.push(aa(1,1,0,1));
        while(!q.empty())
        {
            aa nex,now=q.front();q.pop();
    //        cout<<now.x<<' '<<now.y<<' '<<goal[now.num]<<endl;
            if(key[now.x][now.y]==goal[now.num]&&v[now.x][now.y]<now.num+1)
            {
    //            cout<<now.x<<' '<<now.y<<' '<<goal[now.num]<<endl;
                v[now.x][now.y]=now.num+1;
                nex=aa(now.x,now.y,now.step+1,now.num+1);
                if(nex.num>len){ans=nex.step;break ;}
                q.push(nex);
            }
            else
            {
                for(int i=0;i<4;i++)
                {
                    int bias=a[now.x][now.y][i];
                    if(bias)
                    {
                        nex=aa(now.x+bias*dx[i],now.y+bias*dy[i],now.step+1,now.num);
    //                    cout<<nex.x<<' '<<nex.y<<' '<<goal[nex.num]<<endl;
                        if(nex.num<=v[nex.x][nex.y])continue ;
                        v[nex.x][nex.y]=nex.num;
                        q.push(nex);
                    }
                }
            }
        }
        printf("%d",ans);
        return 0;
    }
    
  • 相关阅读:
    搜索型SQL注入解决方法
    windows10系统下phpstudy安装php8版本
    齐博cms基础教程之认识齐博cms
    thinkphp查找父级栏目及子级栏目的所有文章
    phpstudy+iis搭建php项目
    python办公自动化基础搜索文件
    thinkphp屏蔽ip访问项目做法
    thinkphp使用paypal进行支付的做法详细步骤
    数据库无法插入数据解决方法
    tp5发送邮件适用于常用的php版本做法
  • 原文地址:https://www.cnblogs.com/fangbozhen/p/11766845.html
Copyright © 2011-2022 走看看