牛客对应题目链接:kotori和n皇后 (nowcoder.com)
一、分析题目
算法思路:使用哈希表标记行列以及两个对角线。
注意:输出的时候提前判断⼀下。
二、代码
//值得学习的代码
#include <iostream>
#include <unordered_set>
using namespace std;
typedef long long LL;
int k, t;
int ret = 1e5 + 10; // 第⼀次出现互相攻击的皇后的个数
unordered_set<LL> row; // 标记⾏ y
unordered_set<LL> col; // 标记列 x
unordered_set<LL> dig1; // 标记主对⻆线 y - x
unordered_set<LL> dig2; // 标记副对⻆线 y + x
int main()
{
cin >> k;
for(int i = 1; i <= k; i++)
{
int x, y;
cin >> x >> y;
if(ret != 1e5 + 10) continue;
if(row.count(y) || col.count(x) || dig1.count(y - x) || dig2.count(y + x))
{
ret = i;
}
row.insert(y); col.insert(x); dig1.insert(y - x); dig2.insert(y + x);
}
cin >> t;
while(t--)
{
int i;
cin >> i;
if(i >= ret) cout << "Yes" << endl;
else cout << "No" << endl;
}
return 0;
}
//修改后的代码
#include <iostream>
#include <unordered_set>
using namespace std;
typedef long long LL;
unordered_set<LL> row, col, dg, udg;
const int N=1e9+10;
int main()
{
int k;
cin >> k;
int tmp=1e5+10;
for(int i=1; i<=k; i++)
{
int x, y;
cin >> x >> y;
if(row.count(x) || col.count(y) || dg.count(y-x) || udg.count(x+y))
{
if(tmp==1e5+10) tmp=i;
}
row.insert(x);
col.insert(y);
dg.insert(y-x);
udg.insert(x+y);
}
int t;
cin >> t;
while(t--)
{
int i;
cin >> i;
if(i>=tmp) cout << "Yes" << endl;
else cout << "No" << endl;
}
return 0;
}
三、反思与改进
基本思路是正确的,但是没有仔细看清楚题意,题目要求的是只要在第 i 个皇后放置在棋盘上之后,存在两个皇后可以互相攻击就为 "Yes",所以只需要记录以下第一次可以互相攻击的时候就行。