제출 #1345973

#제출 시각아이디문제언어결과실행 시간메모리
1345973cpismayilmmdv985Toy (CEOI24_toy)C++20
0 / 100
111 ms282608 KiB
#ifdef LOCAL
#include ".debug.hpp"
#else
#define debug(...) 42
#endif
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
using ordered_set = tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>;

const int MXN = 3000;
const int DX[] = {1, -1, 0, 0}, DY[] = {0, 0, 1, -1};
int W, H, K, L, pref[MXN][MXN], targetX = 0, targetY = 0, HB[MXN][MXN], BH[MXN][MXN], HU[MXN][MXN], UH[MXN][MXN], VL[MXN][MXN], VR[MXN][MXN], LV[MXN][MXN], RV[MXN][MXN];
char grid[MXN][MXN];
bool vis[MXN][MXN], used[MXN][MXN];

inline int cnt(const int &x1, const int &y1, const int &x2, const int &y2) {
   return pref[x2][y2] - pref[x2][y1 - 1] - pref[x1 - 1][y2] + pref[x1 - 1][y1 - 1];
}

array<int, 2> inter_point(const int &xh, const int &yh, const int &xv, const int &yv) {
   int xh1 = xh, yh1 = yh + K - 1, xv1 = xv + L - 1, yv1 = yv;
   if (yh <= yv && yv <= yh1 && xv <= xh && xh <= xv1) 
      return {xh, yv};
   return {-1, -1};  
}

inline bool Inter(const int &xh, const int &yh, const int &xv, const int &yv) {
   array<int, 2> point = inter_point(xh, yh, xv, yv);
   return point[0] != -1;
}

bool isValid(const int &type, const int &x, const int &y) {
   if (x < 1 || y < 1 || x > H || y > W)  return false;
   int x1, y1;
   if (!type)  // horizontal line check
      x1 = x, y1 = y + K - 1;
   else        // vertical line check
      x1 = x + L - 1, y1 = y;
   if (x1 < 1 || y1 < 1 || x1 > H || y1 > W) return false;
   return !cnt(x, y, x1, y1);
}

inline bool isfree(const int &x, const int &y) {
   return x >= 1 && y >= 1 && x <= H && y <= W && grid[x][y] != 'X';
}

inline bool isOK(const int &xh, const int &yh, const int &xv, const int &yv) {
   if (!isValid(0, xh, yh) || !isValid(1, xv, yv)) return false;
   return Inter(xh, yh, xv, yv);
}

void dfs(int xh, int yh, int xv, int yv, const int &x, const int &y) {
   vis[x][y] = true;
   if (x == targetX && y == targetY) {
      cout << "YES\n";
      exit(0);
   }
   int oxh = xh, oyh = yh, oxv = xv, oyv = yv;
   for (int d = 0; d < 4; d++) {
      int tox = x + DX[d], toy = y + DY[d]; xh = oxh, yh = oyh, xv = oxv, yv = oyv;
      if (!isfree(tox, toy))  continue;
      if (vis[tox][toy])   continue;
      if (DX[d] == 1) {
         // down -> horizontal line slid down 
         if (isOK(xh + 1, yh, xv, yv)) dfs(xh + 1, yh, xv, yv, tox, toy);
         else {
            if (xh == xv + L - 1) {
               if (!isValid(1, xv + 1, yv))  continue;
               xv++;
            }
            int yh1 = yh + K - 1, lmost = max(1, yh - (yh1 - yv)), rmost = min(W, yv + K - 1); 
            // available range [lmost; rmost] 
            int nyh = HB[xh][yh];
            if (nyh > 0) 
               if (isOK(xh + 1, nyh, xv, yv)) {
                  dfs(xh + 1, nyh, xv, yv, tox, toy);
                  continue;
               }
            nyh = BH[xh][yh];
            if (nyh < MXN) 
               if (isOK(xh + 1, nyh, xv, yv)) {
                  dfs(xh + 1, nyh, xv, yv, tox, toy);
                  continue;
               }
         }
      } else if (DX[d] == -1) {
         // up -> horizontal line slid up
         if (isOK(xh - 1, yh, xv, yv)) dfs(xh - 1, yh, xv, yv, tox, toy);
         else {
            if (xh == xv) {
               if (!isValid(1, xv - 1, yv))  continue;
               xv--;
            }
            // int yh1 = yh + K - 1, lmost = max(1, yh - (yh1 - yv)), rmost = min(W, yv + K - 1); 
            // available range [lmost; rmost] 
            int nyh = HU[xh][yh];
            if (nyh > 0) 
               if (isOK(xh - 1, nyh, xv, yv)) {
                  dfs(xh - 1, nyh, xv, yv, tox, toy);
                  continue;
               }
            nyh = UH[xh][yh];
            if (nyh < MXN) 
               if (isOK(xh - 1, nyh, xv, yv)) {
                  dfs(xh - 1, nyh, xv, yv, tox, toy);
                  continue;
               }
         }
      } else if (DY[d] == 1) {
         // right -> vertical line slid right
         if (isOK(xh, yh, xv, yv + 1)) dfs(xh, yh, xv, yv + 1, tox, toy);
         else {
            if (yv == yh + K - 1) {
               if (!isValid(0, xh, yh + 1))  continue;
               yh++;
            }
            int nyv = VR[xv][yv];
            if (nyv < MXN) 
               if (isOK(xh, yh, xv, nyv)) {
                  dfs(xh, yh, xv, nyv, tox, toy);
                  continue;
               }
            nyv = RV[xv][yv];
            if (nyv > 0) 
               if (isOK(xh, yh, xv, nyv)) {
                  dfs(xh, yh, xv, nyv, tox, toy);
                  continue;
               }
         }
      } else {
         // left -> vertical line slid left
         if (isOK(xh, yh, xv, yv - 1)) dfs(xh, yh, xv, yv - 1, tox, toy);
         else {
            if (yv == yh) {
               if (!isValid(0, xh, yh - 1))  continue;
               yh--;
            }
            int nyv = VL[xv][yv];
            if (nyv < MXN) 
               if (isOK(xh, yh, xv, nyv)) {
                  dfs(xh, yh, xv, nyv, tox, toy);
                  continue;
               }
            nyv = LV[xv][yv];
            if (nyv > 0) 
               if (isOK(xh, yh, xv, nyv)) {
                  dfs(xh, yh, xv, nyv, tox, toy);
                  continue;
               }
         }
      }
   }
}

signed main() {
#ifndef VOID
   cin.tie(nullptr)->sync_with_stdio(false);
#endif

   int XH, YH, XV, YV;
   cin >> W >> H >> K >> L >> XH >> YH >> XV >> YV, XH++, YH++, XV++, YV++;
   swap(XH, YH), swap(XV, YV);
   for (int i = 1; i <= H; i++)
      for (int j = 1; j <= W; j++) {
         cin >> grid[i][j];
         if (!targetX && grid[i][j] == '*')  targetX = i;
         if (!targetY && grid[i][j] == '*')  targetY = j;
      }
   for (int i = 1; i <= H; i++)
      for (int j = 1; j <= W; j++) 
         pref[i][j] = pref[i - 1][j] + pref[i][j - 1] - pref[i - 1][j - 1] + (grid[i][j] == 'X');
   memset(HB, 0, sizeof(HB)), memset(BH, 0x3f, sizeof(BH));
   memset(HU, 0, sizeof(HU)), memset(UH, 0x3f, sizeof(UH));
   for (int i = 1; i <= H; i++) {
      for (int j = 1; j + K - 1 <= W; j++) {
         if (isValid(0, i + 1, j))  HB[i][j] = j;
         HB[i][j] = max(HB[i][j], HB[i][j - 1]);
         if (isValid(0, i - 1, j))  HU[i][j] = j;
         HU[i][j] = max(HU[i][j], HU[i][j - 1]);
      }
      for (int j = W - K + 1; j >= 1; j--) {
         if (isValid(0, i + 1, j))  BH[i][j] = j;
         BH[i][j] = min(BH[i][j], BH[i][j + 1]);
         if (isValid(0, i - 1, j))  UH[i][j] = j;
         UH[i][j] = min(UH[i][j], UH[i][j + 1]);
      }
   }
   memset(VL, 0x3f, sizeof(VL)), memset(VR, 0x3f, sizeof(VR));
   memset(LV, 0, sizeof(LV)), memset(RV, 0, sizeof(RV));
   for (int j = 1; j <= W; j++) {
      for (int i = H - L + 1; i >= 1; i--) {
         if (isValid(1, i, j + 1))  VR[i][j] = i;
         VR[i][j] = min(VR[i][j], VR[i + 1][j]);
         if (isValid(1, i, j - 1))  VL[i][j] = i;
         VL[i][j] = min(VL[i][j], VL[i + 1][j]);
      }
      for (int i = 1; i + L - 1 <= H; i++) {
         if (isValid(1, i, j + 1))  RV[i][j] = i;
         RV[i][j] = max(RV[i][j], RV[i - 1][j]);
         if (isValid(1, i, j - 1))  LV[i][j] = i;
         LV[i][j] = max(LV[i][j], LV[i - 1][j]);
      }
   }
   array<int, 2> inter = inter_point(XH, YH, XV, YV);
   dfs(XH, YH, XV, YV, inter[0], inter[1]);
   cout << "NO\n";

   return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...