这个博客解释原理解释的很好,我就不再多加解释什么了,有兴趣的可以看一下;
<a target=_blank href="http://m.blog.csdn.net/blog/u013480600/39546795">http://m.blog.csdn.net/blog/u013480600/39546795</a>
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
/*
题目意思我就不说了,链接有很详细的说明;
这个题目是个线段相交的暴力枚举类型,数据量不大;
模板加枚举判断,最后选一个最大的就可以了;
*/
typedef struct // 结构体储存所有的多边形;
{
int x[20];
int y[20];
int k;
}Point;
typedef struct // 结构体储存直线AB与线段CD的点;
{
int x,y;
}point;
Point a[20];
// 判断直线AB是否与线段CD相交;
bool Intersect(point A,point B,point C,point D)
{
// 直线方程F(x,y)为:(y-y1)*(x1-x2)-(x-x2)*(y1-y2)=0;
double FC=(C.y-A.y)*(A.x-B.x)-(C.x-A.x)*(A.y-B.y);
double FD=(D.y-A.y)*(A.x-B.x)-(D.x-A.x)*(A.y-B.y);
if(FC*FD<=0) return true;
else return false;
}
// 获得线段CD;
int GetNum(point A,point B,int n)
{
int sum=0;
point C,D;
for(int i=0;i<n;i++){ // 遍历每个多边形;
for(int j=0;j<a[i].k;j++){ // 遍历每个多边形的线段;
C.x=a[i].x[j];
C.y=a[i].y[j];
D.x=a[i].x[(j+1)%a[i].k];
D.y=a[i].y[(j+1)%a[i].k];
if(Intersect(A,B,C,D)){ //直线AB如果与线段CD相交则计数加一;
sum++;
break;
}
}
}
return sum;
}
int main()
{
int t,Case=1,n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i].k);
for(int j=0;j<a[i].k;j++) scanf("%d%d",&a[i].x[j],&a[i].y[j]);
}
if(n==1) // 对n==1进行特判;多边形只有一个;
{
printf("Case %d: 1\n",Case++);
continue;
}
int ans=0;
for(int i=0;i<n;i++){ // 第i个多边形;
for(int j=0;j<a[i].k;j++){ // 第i个多边形内的第j个点;
for(int k=i+1;k<n;k++){ // 第k个多边形;
for(int l=0;l<a[k].k;l++){ //第k个多边形内的第l个点;
// 构成直线AB;
point A,B;
A.x=a[i].x[j];
A.y=a[i].y[j];
B.x=a[k].x[l];
B.y=a[k].y[l];
ans=max(ans,GetNum(A,B,n));
}
}
}
}
printf("Case %d: %d\n",Case++,ans);
}
return 0;
}