标签:
题意:
有一个n×m的地图,上面有三种符号 分别表示向上,向左,向右
有两种操作,A X Y询问从一个点(X,Y)开始最终会走到哪个点或者死循环 , C X Y ch 表示将地图上(X,Y)的符号换成ch
考虑到没有向下的操作,那么陷入死循环的情况只有一种可能即‘>‘ ‘<‘
用分块操作,分成sqrt(n)块,用DP预处理每一块中的点可以到哪个点,-1表示这个点死循环
对于操作A,如果这个点移动到了所在的块的边界处,则输出。否则递归的输出上面的一块
对于操作C,重新对点所在的块进行DP,由于C操作最多只有1W次,又进行了分块处理,所以不会太慢。。。。
Automatic Bakery of Cyberland (ABC) recently bought an n?×?m rectangle table. To serve the diners, ABC placed seats around the table. The size of each seat is equal to a unit square, so there are 2(n?+?m) seats in total.
ABC placed conveyor belts on each unit square on the table. There are three types of conveyor belts: "^", "<" and ">". A "^" belt can bring things upwards. "<" can bring leftwards and ">" can bring rightwards.
Let‘s number the rows with 1 to n from top to bottom, the columns with 1 to m from left to right. We consider the seats above and below the top of the table are rows 0 and n?+?1 respectively. Also we define seats to the left of the table and to the right of the table to be column 0and m?+?1. Due to the conveyor belts direction restriction there are currently no way for a diner sitting in the row n?+?1 to be served.
Given the initial table, there will be q events in order. There are two types of events:
Queries are performed separately meaning that even if the bread got stuck in an infinite loop, it won‘t affect further queries.
The first line of input contains three integers n, m and q (1?≤?n?≤?105,?1?≤?m?≤?10,?1?≤?q?≤?105), separated by a space.
Next n lines, each line contains m characters, describing the table. The characters can only be one of "<^>".
Next q lines, each line describes an event. The format is "C x y c" or "A x y" (Consecutive elements are separated by a space). It‘s guaranteed that 1?≤?x?≤?n,?1?≤?y?≤?m. c is a character from the set "<^>".
There are at most 10000 queries of "C" type.
For each event of type "A", output two integers tx, ty in a line, separated by a space, denoting the destination of (x,?y) is (tx,?ty).
If there is an infinite loop, you should output tx?=?ty?=??-?1.
2 2 3 >> ^^ A 2 1 C 1 2 < A 2 1
1 3 -1 -1
4 5 7 ><<^< ^<^^> >>>^> >^>>^ A 3 1 A 2 2 C 1 4 < A 3 1 C 1 2 ^ A 3 1 A 2 2
0 4 -1 -1 -1 -1 0 2 0 2
For the first sample:
If the bread goes from (2,?1), it will go out of the table at (1,?3).
After changing the conveyor belt of (1,?2) to "<", when the bread goes from (2,?1) again, it will get stuck at "><", so output is (?-?1,??-?1).
#include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; const int maxn=100100; int n,m,q; int kuai,kn; char str[maxn][12]; int dp[maxn][12]; /// dp[y][z]=w: 在第x块中第y行第z列 走到了w号格子 int dfs(int k,int x,int y) { if(dp[x][y]) return dp[x][y]; if(str[x][y]=='^') { int nx=x-1,ny=y; if(nx<1+(k-1)*kuai) { dp[x][y]=nx*(m+2)+ny; } else { dp[x][y]=dfs(k,nx,ny); } } else if(str[x][y]=='>') { int nx=x,ny=y+1; if(ny==m+1) { dp[x][y]=nx*(m+2)+ny; } else if(str[nx][ny]=='<') { dp[x][y]=-1; dp[nx][ny]=-1; } else { dp[x][y]=dfs(k,nx,ny); } } else if(str[x][y]=='<') { int nx=x,ny=y-1; if(ny==0) { dp[x][y]=nx*(m+2)+ny; } else if(str[nx][ny]=='>') { dp[x][y]=-1; dp[nx][ny]=-1; } else { dp[x][y]=dfs(k,nx,ny); } } return dp[x][y]; } /// 在第几块中 void getPOS(int x) { /// Range of Row /// 1+(x-1)*kuai ~ x*kuai for(int r=1+(x-1)*kuai;r<=min(x*kuai,n);r++) { for(int c=1;c<=m;c++) { dfs(x,r,c); } } } void changeIt(int k,int x,int y,char c) { for(int r=1+(k-1)*kuai;r<=min(k*kuai,n);r++) for(int c=1;c<=m;c++) dp[r][c]=0; str[x][y]=c; getPOS(k); } int FindIt(int k,int x,int y) { if(dp[x][y]==-1) return -1; if(k==1) return dp[x][y]; int temp=dp[x][y]; int nx=temp/(m+2); int ny=temp%(m+2); if(ny!=0&&ny!=m+1) return FindIt(k-1,nx,ny); return temp; } int main() { scanf("%d%d%d",&n,&m,&q); for(int i=1;i<=n;i++) scanf("%s",str[i]+1); kuai=int(sqrt(n))+1; kn=n/kuai; if(n%kuai) kn++; for(int i=1;i<=kn;i++) getPOS(i); char cmd[20],ch[10]; int X,Y; while(q--) { scanf("%s",cmd); if(cmd[0]=='A') { scanf("%d%d",&X,&Y); int nn=(X-1)/kuai+1; int ID = FindIt(nn,X,Y); if(ID>=0) printf("%d %d\n",ID/(m+2),ID%(m+2)); else puts("-1 -1"); } else if(cmd[0]=='C') { scanf("%d%d%s",&X,&Y,ch); int nn=(X-1)/kuai+1; changeIt(nn,X,Y,ch[0]); } } return 0; }
Codeforces 487D. Conveyor Belts 分块+DP
标签:
原文地址:http://blog.csdn.net/ck_boss/article/details/44346449