持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情。
镜子
题目描述
农夫约翰的奶牛在农场周围造成了太多麻烦,因此约翰希望对它们保持更密切的关注。
通过在农场的各个位置安装 NN 个反光围栏,他希望能够从 (0,0)(0,0) 位置的房子看到 (a,b)(a,b) 位置的牛棚。
在约翰农场的二维平面图中,围栏 ii 表示为以整数位置坐标 (xi,yi)(xi,yi) 为中心的倾斜 4545 度(如 / 或 ``)的短线段。
例如,以 (3,5)(3,5) 为中心,形如 / 的围栏可以描述为从 (2.9,4.9)(2.9,4.9) 到 (3.1,5.1)(3.1,5.1) 的线段。
每个围栏(以及牛棚的位置)位于不同的位置。
(0,0)(0,0) 和 (a,b)(a,b) 处无围栏。
约翰计划坐在他的房屋 (0,0)(0,0) 处,并直接向右(沿 +x+x 方向)看。
当他的目光从农场的一些反光围栏上反射出来时,他希望能够看到点 (a,b)(a,b)。
不幸的是,他认为其中一个反光围栏的摆放朝向不对,例如应该为 /,却摆成了 ``。
请输出给定反光围栏中,第一个能够通过改变其朝向使得约翰成功看到点 (a,b)(a,b) 的围栏的顺序编号。
如果约翰不需要切换任何围栏的朝向就已经可以看到点 (a,b)(a,b) 则输出 00。
如果约翰无法通过切换单个围栏的朝向使自己看到点 (a,b)(a,b) 则输出 −1−1。
输入格式
第一行包含三个整数 N,a,bN,a,b。
接下来 NN 行,其中第 ii 行描述第 ii 号围栏的位置和朝向。首先包含两个整数 xi,yixi,yi 表示其中心点位置,然后包含一个字符 / 或 `` 表示围栏朝向。
围栏编号从 11 开始。
输出格式
输出第一个能够通过改变其朝向使得约翰成功看到点 (a,b)(a,b) 的围栏的顺序编号。
如果约翰不需要切换任何围栏的朝向就已经可以看到点 (a,b)(a,b) 则输出 00。
如果约翰无法通过切换单个围栏的朝向使自己看到点 (a,b)(a,b) 则输出 −1−1。
数据范围
1≤N≤2001≤N≤200,
−106≤xi,yi,a,b≤106−106≤xi,yi,a,b≤106
输入样例:
5 6 2
3 0 /
0 2 /
1 2 /
3 2 \
1 3 \
输出样例:
4
样例解释
农场的平面图如下所示,其中 HH 表示约翰的房子,BB 表示牛棚:
3 ......
2 //...B
1 .......
0 H../...
0123456
通过改变 (3,2)(3,2) 处的围栏朝向,就可以使约翰看到点 (a,b)(a,b),如下所示:
3 ......
2 //./--B
1 ...|...
0 H--/...
0123456
代码
#include <bits/stdc++.h>
using namespace std;
const int D[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
const int T[2][4]={{3,2,1,0},{1,0,3,2}};
int n;
int mx,my;
vector<int> ax,ay;
int tag[205][205];
bool st[205][205][4];
bool rt[205];
struct Node
{
int x=0,y=0,id=-1;
void f()
{
x=lower_bound(ax.begin(), ax.end(), x)-ax.begin()+1;
y=lower_bound(ay.begin(), ay.end(), y)-ay.begin()+1;
}
void input(int i)
{
cin>>y>>x;
id=i;
}
}pt[205];
void f(vector<int> &v)
{
sort(v.begin(),v.end());
v.resize(unique(v.begin(),v.end())-v.begin());
}
bool sol()
{
memset(st,0,sizeof st);
bool flag=0;
int d=1;
int x=pt[n+1].x,y=pt[n+1].y;
while(1){
if(x==pt[0].x&&y==pt[0].y){
flag=1;
break;
}
if(x<1||x>mx||y<1||y>my||st[x][y][d])break;
st[x][y][d]=1;
if(tag[x][y]!=-1)d=T[tag[x][y]][d];
x+=D[d][0],y+=D[d][1];
}
return flag;
}
int main()
{
cin>>n;
pt[0].input(0);
for(int i=1;i<=n;i++){
pt[i].input(i);
char c;
cin>>c;
rt[i]=(c=='/');
}
for(int i=0;i<=n+1;i++){
ax.push_back(pt[i].x);
ay.push_back(pt[i].y);
}
f(ax),f(ay);
mx=ax.size(),my=ay.size();
memset(tag,-1,sizeof tag);
for(int i=0;i<=n+1;i++){
pt[i].f();
if(i>=1&&i<=n)tag[pt[i].x][pt[i].y]=rt[pt[i].id];
}
if(sol()){
cout<<0;
return 0;
}
for(int i=1;i<=n;i++){
tag[pt[i].x][pt[i].y]^=1;
if(sol()){
cout<<i;
return 0;
}
tag[pt[i].x][pt[i].y]^=1;
}
cout<<-1;
}