kotori和n皇后
(1)测试数据
5
1 2
2 5
3 1
6 7
4 8
2
2
4
(2)关键思路
开4个set,分别存x、y、x + y、x - y;
遍历时,不断查询每个点是否在某个set里面存在,若不存在则分别加入4个set。否则证明和之前的皇后会攻击(把这个i皇后保留下来);
现在来说一下,为什么要保留这四个;
x, or y集合中如果有已经相等的,说明是在同一行或者同一列(同行和同列会互相攻击);
x - y存进集合中如果有已经相等的,说明在同45斜角(x1 - y1 == x2 - y2 => x1 - x2 == y1 - y2);(斜率为1 则 45度)
x + y存进集合中如果有已经相等的,说明在同135斜角(x1 + y1 == x2 + y2 => x1 - x2 == - ( y1 - y2) );(斜率为-1 则 135度)
(3)实现代码
#include <bits/stdc++.h>
using namespace std;
int k; // 总共放置皇后的个数
int x, y;
set<int> s1, s2, s3, s4;
int t; // t次询问
int e; // 每次询问的皇后
int main() {
cin >> k;
// 若 idx 一直 == 0,说明它就一直不会攻击了
// 找到“第一个”
int idx = 0; // 记录下是哪个皇后(i)放下后会互相攻击,那么它之前的i - 1个皇后的不会互相攻击的
for (int i = 1; i <= k; ++i){
cin >> x >> y;
if (s1.count(x) || s2.count(y) || s3.count(x - y) || s4.count(x + y)) {
// 若是已经修改了,就不用再更新了
if (!idx) idx = i;
}
s1.insert(x);
s2.insert(y);
s3.insert(x - y) ;
s4.insert(x + y);
}
cin >> t;
while (t--) {
cin >> e;
if (idx && e >= idx) cout << "Yes" << endl;
else cout << "No" << endl;
}
return 0;
}