问题描述
在一个n×m的国际象棋棋盘上有很多车(Rook),其中车可以攻击他所属的一行或一列,包括它自己所在的位置。
现在还有很多询问,每次询问给定一个棋盘内部的矩形,问矩形内部的所有格子是否都被车攻击到?
输入描述
输入文件包含多组数据,第一行为数据组数T。 每组数据有4个正整数n,m,K,Q。 K为车的数量,Q为询问的个数。 接下来有K行,每行两个整数x,y , 表示车所在的坐标。 再接下来有Q行,每行4个整数x1,y1,x2,y2,表示询问的矩形的左下角与右上角的坐标。 1≤n,m,K,Q≤100,000. 1≤x≤n,1≤y≤m. 1≤x1≤x2≤n,1≤y1≤y2≤m.
输出描述
对于每组询问,输出Yes或No。
输入样例
2 2 2 1 2 1 1 1 1 1 2 2 1 2 2 2 2 2 1 1 1 1 2 2 1 2 2
输出样例
Yes No Yes
一个矩形要被全部攻击到要么所有列都有车要么所有行都有车,记录一下每列每行是否有车,算下前缀和。
#include <cstdio> #include <cstring> using namespace std; const int N = 1e5 + 10; int row[N], col[N]; int n, m, k, q, t; int main() { scanf("%d", &t); while (t--) { memset(row, 0, sizeof(row)); memset(col, 0, sizeof(col)); scanf("%d%d%d%d", &n, &m, &k, &q); int x, y, x1, y1, x2, y2; for (int i = 1; i <= k; i++) { scanf("%d%d", &x, &y); row[x] = col[y] = 1; } for (int i = 2; i <= n; i++) row[i] += row[i - 1]; for (int i = 2; i <= m; i++) col[i] += col[i - 1]; for (int i = 1; i <= q; i++) { scanf("%d%d%d%d", &x1, &y1, &x2, &y2); if ((y2 - y1 + 1) == (col[y2] - col[y1 - 1])) printf("Yes\n"); else if ((x2 - x1 + 1) == (row[x2] - row[x1 - 1])) printf("Yes\n"); else printf("No\n"); } } return 0; }