zoukankan      html  css  js  c++  java
  • Codeforces Round #331 (Div. 2) E. Wilbur and Strings dfs乱搞

    E. Wilbur and Strings

    Time Limit: 20 Sec

    Memory Limit: 256 MB

    题目连接

    http://codeforces.com/contest/596/problem/E

    Description

    Wilbur the pig now wants to play with strings. He has found an n by m table consisting only of the digits from 0 to 9 where the rows are numbered 1 to n and the columns are numbered 1 to m. Wilbur starts at some square and makes certain moves. If he is at square (xy) and the digit d (0 ≤ d ≤ 9) is written at position (xy), then he must move to the square (x + ady + bd), if that square lies within the table, and he stays in the square (xy) otherwise. Before Wilbur makes a move, he can choose whether or not to write the digit written in this square on the white board. All digits written on the whiteboard form some string. Every time a new digit is written, it goes to the end of the current string.

    Wilbur has q strings that he is worried about. For each string si, Wilbur wants to know whether there exists a starting position (xy) so that by making finitely many moves, Wilbur can end up with the string si written on the white board.

    Input

    The first line of the input consists of three integers nm, and q (1 ≤ n, m, q ≤ 200) — the dimensions of the table and the number of strings to process, respectively.

    Each of the next n lines contains m digits from 0 and 9 giving the table itself.

    Then follow 10 lines. The i-th of them contains the values ai - 1 and bi - 1 ( - 200 ≤ ai, bi ≤ 200), i.e. the vector that Wilbur uses to make a move from the square with a digit i - 1 in it.

    There are q lines that follow. The i-th of them will contain a string si consisting only of digits from 0 to 9. It is guaranteed that the total length of these q strings won't exceed 1 000 000.

    Output

    For each of the q strings, print "YES" if Wilbur can choose x and y in order to finish with this string after some finite number of moves. If it's impossible, than print "NO" for the corresponding string.

    Sample Input

    1 1 2
    0
    1 1
    1 1
    1 1
    1 1
    1 1
    1 1
    1 1
    1 1
    1 1
    1 1
    0000000000000
    2413423432432

    Sample Output

    YES
    NO

    HINT

    题意

    给你n*m的矩阵,每个矩阵里面都是0-9的数字,假设你踩到了(x,y),那么下一步就会在(x+ad,y+bd) ad和bd会给你 d是(x,y)的数值

    然后你从不同的起点出发,会得到不同的字符串

    然后有Q次询问,给你一个字符串,问你这个字符串是不是可能是之前的走出的字符串的子序列

    题解:

    暴力DP,dp[x][y][t],表示你在(x,y),你想得到字符t,你最近的一步是在哪儿

    这个dp由dfs可以很容易得到

    然后询问的时候,就直接暴力就好了

    代码

    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<stdio.h>
    using namespace std;
    
    int n,m,q;
    char s2[10000006];
    char s[205][205];
    int vis[205][205];
    int dp[205*205][20];
    int dx[10];
    int dy[10];
    vector<int> Q;
    int id(int x,int y)
    {
        return x*m+y;
    }
    void dfs(int x,int y)
    {
        vis[x][y]=1;
        int t = (s[x][y]-'0'),p = id(x,y);
        int xx = x+dx[t],yy = y+dy[t];
        if(xx<0||xx>=n||yy<0||yy>=m)
            dp[p][t]=p;
        else
        {
            int v = id(xx,yy);
            dp[p][t]=id(xx,yy);
            if(vis[xx][yy]==0)dfs(xx,yy);
            for(int i=0;i<10;i++)
                if(i!=t)
                    dp[p][i]=dp[v][i];
        }
    }
    
    int check(char s2[])
    {
        int len = strlen(s2);
        for(int i=0;i<Q.size();i++)
        {
            int x = Q[i];
            for(int j=0;j<len;j++)
            {
                x = dp[x][s2[j]-'0'];
                if(x<0)break;
            }
            if(x>=0)return 1;
        }
        return 0;
    }
    
    int main()
    {
        memset(dp,-1,sizeof(dp));
        scanf("%d%d%d",&n,&m,&q);
        for(int i=0;i<n;i++)
            scanf("%s",s[i]);
        for(int i=0;i<10;i++)
            scanf("%d%d",&dx[i],&dy[i]);
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(!vis[i][j])
                {
                    dfs(i,j);
                    Q.push_back(id(i,j));
                }
            }
        }
        for(int i=0;i<q;i++)
        {
            scanf("%s",s2);
            if(check(s2))printf("YES
    ");
            else puts("NO");
        }
    }
  • 相关阅读:
    Python基础----内置函数补充、匿名函数、递归函数
    为arm-linux开发板挂载基于nfs的根文件系统
    vsftp上传553 Could not create file错误解决
    在itop4412移植linux4.14和设备树遇到的问题及解决
    itop4412uboot中支持usbhub
    上下界网络流
    lca(最近公共祖先(在线)) 倍增法详解
    lca(最近公共祖先(离线))
    最小费用最大流
    spfa模板+讲解
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4973758.html
Copyright © 2011-2022 走看看