zoukankan      html  css  js  c++  java
  • UVA1714 Keyboarding(bfs)

    UVA1714 Keyboarding

    bfs

    坑点很多的一题(由于一本通的辣鸡翻译会错题意*n)。

    1.多组数据

    2.如果某方向上没有不同字符光标不会动

    我们每次预处理出每个点向四个方向下次到达的点。然后跑bfs即可

    注意bfs每次只能扩展一层(也就是说距离dis每次最多只能+1,否则无法保证最优性)!(所以不要把移动和选择写到一起qwq)

    处理字符用map就好了

    (卡了我一整天qwq)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<cmath>
    #include<map>
    using namespace std;
    inline int mini(int &a,int &b) {return a<b ?a:b;}
    int d1[4]={0,1,0,-1};
    int d2[4]={1,0,-1,0};
    int n,m,len,a[52][52],b[10002],vis[52][52];
    struct data{int x,y,step,dis;}dir[4][52][52];
    map <char,int> Map;
    void draw(){ //字符处理成数字好写
        for(int i=0;i<=9;++i) Map[(char)('0'+i)]=i+1;
        for(int i=0;i<26;++i) Map[(char)('A'+i)]=i+11;
        Map['-']=37; Map['*']=38;
    } 
    void pretreatment(){ //预处理四个方向上下次可到的点
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
                for(int k=0;k<4;++k){
                    int r1=i,r2=j;
                    while(a[r1][r2]==a[r1+d1[k]][r2+d2[k]])    r1+=d1[k],r2+=d2[k];
                    dir[k][i][j]=(data){r1,r2,0,0};
                }
    } 
    inline int bfs(){
        memset(vis,0,sizeof(vis));
        queue <data> h; int ans=0;
        int k=1;
        while(b[k]==a[1][1]&&k<=len) ++k;
        h.push((data){1,1,k,k-1}); vis[1][1]=k; //特判在起点选取的情况
        while(!h.empty()){
            data u=h.front(); h.pop();
            if(a[u.x][u.y]==b[u.step]){ //选择(千万不能和移动写在一起)
                if(u.step==len) {ans=u.dis+1; break;}
                vis[u.x][u.y]=u.step+1;
                h.push((data){u.x,u.y,u.step+1,u.dis+1});
                continue;
            }
            for(int i=0;i<4;++i){
                data to=dir[i][u.x][u.y]; to.x+=d1[i]; to.y+=d2[i]; //由于我的预处理没写完整要再加一次
                if(to.x<1||to.x>n||to.y<1||to.y>m) continue;
                if(vis[to.x][to.y]>=u.step) continue;
                vis[to.x][to.y]=u.step;
                h.push((data){to.x,to.y,u.step,u.dis+1});
            }
        }
        return ans;
    }
    int main(){
        //freopen("UVA1714.in","r",stdin);
        draw();
        char q[10002];
        while(scanf("%d",&n)!=EOF) //多组数据
        {
            scanf("%d",&m);
            for(int i=1;i<=n;++i){
                scanf("%s",q);
                for(int j=0;j<m;++j) a[i][j+1]=Map[q[j]];
            }
            scanf("%s",q); len=strlen(q);
            for(int i=0;i<len;++i) b[i+1]=Map[q[i]];
            b[++len]=38; //b数组存操作串
            pretreatment();
            printf("%d
    ",bfs());
        }
        return 0;
    }
  • 相关阅读:
    iphone inline video fragments
    input text focus去掉默认光影
    ios html5 audio 不能自动播放
    跑马灯实现新闻滚动 鼠标放上去停 移开继续滚动
    转:理解WinCE bulid过程
    C语言sendto()函数:经socket传送数据
    WaitForSingleObject用法介绍
    CoInitializeEx()
    转:select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET
    setsocketopt()
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/9596690.html
Copyright © 2011-2022 走看看