小L最近看上了一个女同学叫小A,但是小A是个高冷的姑娘,所以她给小L出了个难题,她给小L留下了一张纸条,上面只有一个坐标,和一个时间,所以小L需要在规定时间找到这个坐标的地点,并在那个时间到哪个地点等待小A,但是很无奈,小L不是一个地理通,所以他找到了小A的室友,想知道一点信息,小A的室友就给了小L一共N个城市边角的坐标(假设每个城市都是一个M多边形),小L需要做的就是判断小A是不是在这个城市(在边上或在城市的顶点也算在城市中),所以小L就找到了神奇的ACMer,大家帮帮他找到他的小A吧
测试数据有多组,你需要处理到文件结尾(EOF),每组的格式如下:
第一行为一个坐标X,Y 和两个数字N,M(-1000<=X,Y<=1000 ,1<=N<=100 ,3<=M<=100)
接下来N行每行有M个坐标(坐标将以逆时针的顺序给出,其中坐标都是整数)
输出在第几个城市
5 5 2 42 0 4 0 4 4 2 4 2 0 6 0 6 6 2 6
2
题目保证一定存在答案,并且只会在一个城市中(即使城市有重叠)。而且给定的城市的多边形是凸多边形。
比赛时,做的最逗比的一个题,简直简单啊,我却还傻X的没做出来,之前思路错了,样例没过(其实也没错,只要加个fabs就差不多过了),之后看到了模板,就兴冲冲敲起模板,真他妈浪费时间啊。。之后也没过。。唉,真想抱着个人哭啊。。
思路:先全部输入,然后逐个城市来,利用从第一个点开始划分三角形来算出整个城市的面积,再利用这个就可以算出点和城市每两个点(逆时针一圈)组成三角形面积之和,如果这两个面积相等的话点就在城市里。
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef struct
{
double x, y;
}point;
struct node
{
point pos[110];
}city[110];
double area2(point A, point B, point C)
{
double tmp1 = A.x * B.y + C.x * A.y + B.x * C.y;
double tmp2 = C.x * B.y + A.x * C.y + B.x * A.y;
return fabs(tmp1 - tmp2);
}
int main()
{
point p;
int n, m;
while(scanf("%lf %lf %d %d", &p.x, &p.y, &n, &m)!=EOF)
{
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
scanf("%lf %lf", &city[i].pos[j].x, &city[i].pos[j].y);
}
}
int i;
for(i=0; i<n; i++)
{
double ar1=0, ar2=0;
for(int j=1; j<m-1; j++) //算出整个城市的面积
{
ar1+=area2(city[i].pos[0], city[i].pos[j], city[i].pos[j+1]);
}
for(int j=0; j<m-1; j++) //算出点和城市每两个点(逆时针一圈)组成三角形面积之和
{
ar2+=area2(p, city[i].pos[j], city[i].pos[j+1]);
}
ar2+=area2(p, city[i].pos[m-1], city[i].pos[0]);
if(fabs(ar1-ar2)<=1e-7)break;
}
printf("%d\n", i+1);
}
return 0;
}
ZZUOJ - 1245 - 寻找幸福的小L ( 郑州大学第八届ACM大学生程序设计竞赛正式赛F题)
原文:http://blog.csdn.net/u014355480/article/details/41807835