zoukankan      html  css  js  c++  java
  • [CF232E]Quick Tortoise

    题目大意:
      给你一个$n imes m(n,mleq 500)$的格子,有一些是障碍物。从一个格子出发只能向下或向右走,有$q$组询问,每次询问从一个点是否能够到达另一个点。

    思路:
      分治。
      两点间的路径必然会经过两点间的某条竖线。
      我们可以二分一个区间内中间一条线$mid$,
      对于$mid$左边的点,求出到$mid$为止往右下走能够到达的点,
      对于$mid$右边的点,求出从$mid$开始往右下走会被哪些点到达。
      这可以用bitdet来存。
      对于不经过这条竖线的路径,可以往下递归查找。
      回答询问时,只需要找到一开始选的两点之间的竖线,然后判一下一个点能到达的点和另一个点被到达的点有没有交集即可。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<bitset>
     4 inline int getint() {
     5     register char ch;
     6     while(!isdigit(ch=getchar()));
     7     register int x=ch^'0';
     8     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
     9     return x;
    10 }
    11 inline bool getblock() {
    12     register char ch=getchar();
    13     while(ch!='.'&&ch!='#') ch=getchar();
    14     return ch=='.';
    15 }
    16 const int N=502,logN=9;
    17 int n,m;
    18 bool map[N][N];
    19 std::bitset<N> f[N][N][logN],g[N][N][logN];
    20 void solve(const int &l,const int &r,const int &k) {
    21     if(l>r) return;
    22     const int mid=(l+r)/2;
    23     solve(l,mid-1,k+1);
    24     solve(mid+1,r,k+1);
    25     for(register int i=n;i;i--) {
    26         if(map[i][mid]) {
    27             f[i][mid][k][i]=true;
    28             f[i][mid][k]|=f[i+1][mid][k];
    29         }
    30         for(register int j=mid-1;j>=l;j--) {
    31             if(map[i][j]) {
    32                 f[i][j][k]|=f[i+1][j][k]|f[i][j+1][k];
    33             }
    34         }
    35     }
    36     for(register int i=1;i<=n;i++) {
    37         if(map[i][mid]) {
    38             g[i][mid][k][i]=true;
    39             g[i][mid][k]|=g[i-1][mid][k];
    40         }
    41         for(register int j=mid+1;j<=r;j++) {
    42             if(map[i][j]) {
    43                 g[i][j][k]|=g[i-1][j][k]|g[i][j-1][k];
    44             }
    45         }
    46     }
    47 }
    48 int calc(const int &l,const int &r,const int &k,const int &y1,const int &y2) {
    49     const int mid=(l+r)/2;
    50     if(y2<mid) return calc(l,mid-1,k+1,y1,y2);
    51     if(y1>mid) return calc(mid+1,r,k+1,y1,y2);
    52     return k;
    53 }
    54 inline bool check(const int &x1,const int &y1,const int &x2,const int &y2) {
    55     if(x1>x2||y1>y2) return false;
    56     const int k=calc(1,m,0,y1,y2);
    57     return (f[x1][y1][k]&g[x2][y2][k]).count();
    58 }
    59 int main() {
    60     n=getint(),m=getint();
    61     for(register int i=1;i<=n;i++) {
    62         for(register int j=1;j<=m;j++) {
    63             map[i][j]=getblock();
    64         }
    65     }
    66     solve(1,m,0);
    67     for(register int q=getint();q;q--) {
    68         const int x1=getint(),y1=getint(),x2=getint(),y2=getint();
    69         puts(check(x1,y1,x2,y2)?"Yes":"No");
    70     }
    71     return 0;
    72 }
  • 相关阅读:
    打印九九乘法三角形的各种思路
    7-14 倒数第N个字符串
    7-13 求阶乘序列前N项和
    7-12统计学生成绩
    Discrete Mathematics and Its Applications | 1 CHAPTER The Foundations: Logic and Proofs | 1.3 Propositional Equivalences
    Discrete Mathematics and Its Applications | 1 CHAPTER The Foundations: Logic and Proofs | 1.2 Applications of Propositional Logic
    Discrete Mathematics and Its Applications | 1 CHAPTER The Foundations: Logic and Proofs | 1.1 Propositional Logic
    [Mac Terminal] ___切换到其他路径和目录
    [Mac Terminal] ___MAC终端清屏快捷键
    部署flask到linux服务器
  • 原文地址:https://www.cnblogs.com/skylee03/p/8252304.html
Copyright © 2011-2022 走看看