标签:
题意:
有一个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