曲线谜题
时间限制 : - MS 空间限制 : - KB
评测说明 : 1s 256MB
问题描述
果老师在玩一个曲线迷题游戏。
在这个游戏中,有一个 R * C 的矩形网格,对于整数 i(1 <= i <= N) 会被填入网格中
(x[i]1,y[i ]1)和 (x[i]2,y[i]2) 两个网格。
现在果老师会尝试用曲线连接所有两两相同的数字,使得曲线不会出网格外并且不会交叉。
果老师希望你能帮他判断是否可能。
输入格式
输出的第一行为三个正整数R,C,N。
接下来的N行,每行两个坐标(x[i]1,y[i ]1)和 (x[i]2,y[i]2) 。表示 i 填入的网格坐标。
给出的坐标点都不重合,所有输入的值都是整数。
输出格式
输入可能输出
YES
,否则输出NO
。
思路:
这道题比较难
先来思考一下:
只有两个交点,如图所示。
可见,相交的点都是由两端都在边上的点。
因为两端没有在四边上的会留出空隙,供其他线穿过,不影响整体。
所以我们只讨论两端都在边上的点。
我们将上图转化为二维:
然后连点:
可见,相交的点就是上图中的两个交点。
这道题就变得简单了。
第一步:将图像的四条边展开
第二步:按特定顺序排序
第三步:将颜色入栈,如果栈顶与将要入栈的颜色相同,弹出栈顶。
第四步:如果栈为空,输出"YES",否则输出"NO"。
第一步:
bool check(int x, int y)
{
if(x == 0 || x == r || y == 0 || y == c)
return true;
return false;
}
int choose(int x, int y)
{
if(x == 0)
return 1;
if(y == c)
return 2;
if(x == r)
return 3;
if(y == 0)
return 4;
}
//......
for(int i=1;i<=n;i++)
{
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(check(x1,y1)==true&&check(x2,y2)==true)
{
member[++cnt].x = x1;
member[cnt].y = y1;
member[cnt].id = choose(x1,y1);
member[cnt].color = i;
member[++cnt].x = x2;
member[cnt].y = y2;
member[cnt].id = choose(x2,y2);
member[cnt].color = i;
}
}
第二步:
bool operator < (node x, node y) //重载
{
if(x.id == y.id)
{
if(x.id == 1)
return x.y < y.y;
if(x.id == 2)
return x.x < y.x;
if(x.id == 3)
return x.y > y.y;
if(x.id == 4)
return x.x > y.x;
}
return x.id < y.id;
}
//......
sort(member + 1, member + 1 + cnt)
第三步:
for(int i=1;i<=cnt;i++)
{
if(!stk.empty() && member[i].color == stk.top())
stk.pop();
else
stk.push(member[i].color);
}
第四步:
if(stk.empty())
{
printf("YES\n");
}
else
{
printf("NO\n");
}
return 0;
AC代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e8;
int c,r,n;
struct node
{
int x;
int y;
int color;
int id;
};
node member[N];
bool operator < (node x, node y)
{
if(x.id == y.id)
{
if(x.id == 1)
return x.y < y.y;
if(x.id == 2)
return x.x < y.x;
if(x.id == 3)
return x.y > y.y;
if(x.id == 4)
return x.x > y.x;
}
return x.id < y.id;
}
bool check(int x, int y)
{
if(x == 0 || x == r || y == 0 || y == c)
return true;
return false;
}
int choose(int x, int y)
{
if(x == 0)
return 1;
if(y == c)
return 2;
if(x == r)
return 3;
if(y == 0)
return 4;
}
stack<int> stk;
int main()
{
int cnt = 0;
scanf("%d%d%d",&r,&c,&n);
for(int i=1;i<=n;i++)
{
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(check(x1,y1)==true&&check(x2,y2)==true)
{
member[++cnt].x = x1;
member[cnt].y = y1;
member[cnt].id = choose(x1,y1);
member[cnt].color = i;
member[++cnt].x = x2;
member[cnt].y = y2;
member[cnt].id = choose(x2,y2);
member[cnt].color = i;
}
}
sort(member + 1, member + 1 + cnt);
for(int i=1;i<=cnt;i++)
{
if(!stk.empty() && member[i].color == stk.top())
stk.pop();
else
stk.push(member[i].color);
}
if(stk.empty())
{
printf("YES\n");
}
else
{
printf("NO\n");
}
return 0;
}
The end
最后:制作不易,点个赞吧,求求了