codeforces 596E Wilbur and Strings(DFS)
2015-11-24 21:53
281 查看
题目链接
E. Wilbur and Strings
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
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 (x,
y) and the digit d (0 ≤ d ≤ 9) is written at position (x,
y), then he must move to the square (x + ad,
y + bd), if that square lies within the table, and he stays in the square (x,
y) 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 (x,
y) 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
n, m, 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 test(s)
Input
Output
Input
Output
Note
In the first sample, there is a 1 by
1 table consisting of the only digit 0. The only move that can be made is staying on the square. The first string can be written on the white board by writing
0 repeatedly. The second string cannot be written as there is no
2 on the table.
题意:n*m的矩阵,每个格子内有一个(0-9)的数字。若当前在格子(i,j)那么下一步必须前往格子(i+a[i],j+b[j])(当且仅当该格子在矩阵内,否则任然在原地)。到了一个格子可以选择盖格子上的数字并将它加入已选数字的末尾,也可以不选。有q次询问,每次询问一个字符串,求解任选起点,在有限的步数内能否获得该字符串。
题解:根据题意建图。有一个特点,每一个格子出度最大为1。那么以任意一个点为起点一直走,那么路径一定唯一,末尾要么是个点,要么是个环。我们把环缩点,再反向建图,每次询问的一个字符串的时候,从入度为0的点开始,DFS遍历图,能匹配则匹配,贪心求解即可。由于图是个DAG,每个点的入度最大为1,那么每次询问,每个点最多只访问一次。复杂度O(q*n*m)
代码如下:
E. Wilbur and Strings
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
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 (x,
y) and the digit d (0 ≤ d ≤ 9) is written at position (x,
y), then he must move to the square (x + ad,
y + bd), if that square lies within the table, and he stays in the square (x,
y) 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 (x,
y) 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
n, m, 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 test(s)
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
Output
YES NO
Input
4 2 5 01 23 45 67 0 1 0 -1 0 1 0 -1 0 1 0 -1 0 1 0 -1 0 1 0 -1 0000000000 010101011101 32232232322 44343222342444324 6767
Output
YES
YES
YES NOYES
Note
In the first sample, there is a 1 by
1 table consisting of the only digit 0. The only move that can be made is staying on the square. The first string can be written on the white board by writing
0 repeatedly. The second string cannot be written as there is no
2 on the table.
题意:n*m的矩阵,每个格子内有一个(0-9)的数字。若当前在格子(i,j)那么下一步必须前往格子(i+a[i],j+b[j])(当且仅当该格子在矩阵内,否则任然在原地)。到了一个格子可以选择盖格子上的数字并将它加入已选数字的末尾,也可以不选。有q次询问,每次询问一个字符串,求解任选起点,在有限的步数内能否获得该字符串。
题解:根据题意建图。有一个特点,每一个格子出度最大为1。那么以任意一个点为起点一直走,那么路径一定唯一,末尾要么是个点,要么是个环。我们把环缩点,再反向建图,每次询问的一个字符串的时候,从入度为0的点开始,DFS遍历图,能匹配则匹配,贪心求解即可。由于图是个DAG,每个点的入度最大为1,那么每次询问,每个点最多只访问一次。复杂度O(q*n*m)
代码如下:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h> #include<math.h> #include<vector> #include<queue> #include<stack> #include<map> #include<set> #include<list> typedef __int64 LL; typedef unsigned __int64 LLU; const int nn=210; const int inf=0x3fffffff; const LL inf64=(LL)inf*inf; using namespace std; int n,m,q; char stu[nn][nn]; int sz[nn*nn]; int tu[nn][nn]; int a[nn],b[nn]; char s[nn*10000]; struct node { int en,next; }E[nn*nn]; int p[nn*nn],num; int rd[nn*nn]; void init() { memset(rd,0,sizeof(rd)); memset(p,-1,sizeof(p)); num=0; } void add(int st,int en) { rd[en]++; E[num].en=en; E[num].next=p[st]; p[st]=num++; } bool check(int x,int y) { return x>=1&&x<=n&&y>=1&&y<=m; } int ID(int x,int y) { return (x-1)*m+y; } int dfn[nn*nn],low[nn*nn]; int cnt; bool insta[nn*nn]; stack<int>sta; bool use[nn*nn][15]; bool vis[nn*nn]; void dfs(int id) { sta.push(id); insta[id]=true; dfn[id]=low[id]=++cnt; int i,w; for(i=p[id];i+1;i=E[i].next) { w=E[i].en; if(dfn[w]==-1) { dfs(w); low[id]=min(low[id],low[w]); } else if(insta[w]) { low[id]=min(low[id],dfn[w]); } } if(dfn[id]==low[id]) { while(1) { int ix=sta.top(); if(ix!=id) { vis[ix]=false; rd[id]=0; } sta.pop(); insta[ix]=false; use[id][sz[ix]]=true; if(ix==id) break; } } } void tarjan() { memset(dfn,-1,sizeof(dfn)); memset(insta,false,sizeof(insta)); memset(use,false,sizeof(use)); memset(vis,true,sizeof(vis)); cnt=0; int i,j,w; for(i=1;i<=n*m;i++) { if(dfn[i]==-1) { dfs(i); } } } bool solve(int id,int ix) { if(ix==-1) return true; int i,w; bool re=false; for(i=p[id];i+1;i=E[i].next) { w=E[i].en; if(!vis[w]) continue; if(use[w][s[ix]-'0']) { re=re||solve(w,ix-1); } else { re=re||solve(w,ix); } } return re; } int main() { int i,j; while(scanf("%d%d%d",&n,&m,&q)!=EOF) { for(i=1;i<=n;i++) { scanf("%s",stu[i]); for(j=0;j<m;j++) { tu[i][j+1]=stu[i][j]-'0'; sz[ID(i,j+1)]=tu[i][j+1]; } } for(i=0;i<=9;i++) { scanf("%d%d",&a[i],&b[i]); } init(); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { if(check(i+a[tu[i][j]],j+b[tu[i][j]])) { add(ID(i+a[tu[i][j]],j+b[tu[i][j]]),ID(i,j)); } } } tarjan(); while(q--) { scanf("%s",s); int ls=strlen(s); for(i=1;i<=n*m;i++) { if(rd[i]==0) { int fuck=ls; while(fuck>=1) { if(use[i][s[fuck-1]-'0']) { fuck--; } else break; } if(fuck==0) { puts("YES"); break; } if(solve(i,fuck-1)) { puts("YES"); break; } } } if(i>n*m) { puts("NO"); } } } return 0; }
相关文章推荐
- 32.CELL⾃适应⾼度
- android112 c代码打印日志,c反编译调用java
- Mockito实现原理探析 -- Mockito.when(...).thenReturn(...)的一个简化实现
- 使用requirejs加载多个插件
- 分配病房(C程序设计进阶第6周)
- Android任务和返回栈完全解析,细数那些你所不知道的细节
- NSnotification通知
- SpringMVC介绍之Validation
- eclipse连接oracle11g教程(win7系统)
- python基础_Scrapy爬虫基础学习一
- java中堆栈和队列的实现方式
- 响应式的前端框架bootstrap
- PAT1097 Deduplication on a Linked List
- Leetcode168: House Robber II
- Runtime
- iOS视图生命周期
- LBS地理位置距离计算方法之geohash算法
- application对象
- linux文件按最新时间排序
- 字符串处理