直接用暴力扫描的做法,注意叉乘可以用来判断两直线是否相交。
如果线段P1P2和直线Q1Q2相交,则线段P1P2跨立直线Q1Q2,
即:( P1 - Q1 ) × ( Q2 - Q1 ) * ( Q2 - Q1 ) × ( P2 - Q1 ) >= 0。
#include <iostream>
#include <cstdio>
using namespace std;
struct node
{
int k;
int x[15],y[15];
}Point[15];
int Judge(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4) //叉乘判断
{
int a=x3-x1,b=y3-y1;
int c=x2-x1,d=y2-y1;
int e=x4-x1,f=y4-y1;
if((a*d-b*c)*(c*f-d*e)>=0)return 1;
return 0;
}
int main()
{
int T;
int N;
int K,i,j,Case=0,p,w,sum,Max;
scanf("%d",&T);
while(T--)
{
Max=0;
scanf("%d",&N);
for(i=1;i<=N;i++)
{
scanf("%d",&K);
Point[i].k=K;
for(j=1;j<=K;j++)
{
scanf("%d%d",&Point[i].x[j],&Point[i].y[j]);
}
}
if(N==1) //一个图形的情况要单独讨论
{
printf("Case %d: 1\n",++Case);
continue;
}
for(i=1;i<N;i++)
{
for(j=i+1;j<=N;j++)
{
for(int t=1;t<=Point[i].k;t++) //枚举选中的图形的每个点
{
for(int r=1;r<=Point[j].k;r++) //枚举另一选中的图形的每个点
{
sum=2; //每次需重置为2
for(p=1;p<=N;p++) //选中除另外两个图形的图形
{
if(p==i||p==j)continue;
for(w=1;w<=Point[p].k-1;w++) //选择第三个图形中的点
{
if(Judge(Point[i].x[t],Point[i].y[t],Point[j].x[r],Point[j].y[r],Point[p].x[w],Point[p].y[w],Point[p].x[w+1],Point[p].y[w+1]))//判断两直线是否相交
{
sum++;
break; //切记要break;以免重复加
}
}
}
if(sum>Max)Max=sum; //把大的值赋予Max
}
}
}
}
printf("Case %d: %d\n",++Case,Max);
}
return 0;
}