这个博客解释原理解释的很好,我就不再多加解释什么了,有兴趣的可以看一下;
<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; }