【思维构造】 Omkar and Determination CF1583C

Omkar and Determination

易知:

如果一个格子是不可退出,那么这个格子为X,或从这个格子向左(向上)走的过程中一定会出现这种情况:

?X

X?

即路径上当前格子的左边和上边都是X

同理,如果一个格子是可退出的,那么这个格子为且向左和向上走的过程中不会出现上述情况。

接下来我们考虑无法判断一个格子是否为空的条件。(已知网格中所有格子是否可以退出)

假设网格为n * m的矩形,当前格子为 [x, y]。那么 [x, y] 是否为空只取决于“以[x, y]为右下角的矩形所包含的所有格子”。

我们假设无论[x, y]是否为空都可以向左或向上移动(当然前提是移动到的格子为空~)。如果[x, y]可以退出(不考虑自身),则可以判断[x, y]是否为,反之则不能。具体如下:

  1. [x, y]可以退出(不考虑自身)。如果[x, y]可以退出(考虑自身),那么[x, y]为;如果[x, y]不能退出(考虑自身),那么[x, y]为X
  2. [x, y]不能退出(不考虑自身),即在“出去”的过程中会遇到文章开头处提到那种情况。那么无论[x, y]是否为空,[x, y]都不能退出(考虑自身)。

综上,已知一个网格中所以格子是否可以退出时,这个网格“可确定”(能退出每一个格子是否为空)的充要条件为网格中不存在文章开头处提到的情况

 Code

#include <bits/stdc++.h>
#define int long long
#define sz(a) ((int)a.size())
using namespace std;
using PII = pair<int, int>;
const int N = 2e5 + 10;

int n, m;
int x1, x2; // x1列 ~ x2列

void solve() {
	cin >> n >> m;
	vector <string> s(n + 1);
	vector <int> lie(m + 1, 0);
	for (int i = 1; i <= n; i ++) {
		cin >> s[i];
		s[i].insert(s[i].begin(), '0');
		if (i != 1) {
			// i == 1时s[i-1][j]是无效的!!!
			for (int j = 1; j <= m; j ++) {
				if (s[i][j - 1] == 'X' && s[i - 1][j] == 'X') {
					lie[j] = 1;
				}
			}
		}
	}
	
	for (int j = 1; j <= m; j ++) {
		lie[j] += lie[j - 1];
	}
	
	int q; cin >> q;
	while (q --) {
		cin >> x1 >> x2;
		if (lie[x2] - lie[x1] == 0) {
			cout << "YES\n";
		} else {
			cout << "NO\n";
		}
	}
}

signed main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int t = 1;
//	cin >> t; cin.get();
	while (t --) solve();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值