杭电3952

来源:互联网 发布:u盘格式化恢复数据 编辑:程序博客网 时间:2024/06/05 15:41

直接用暴力扫描的做法,注意叉乘可以用来判断两直线是否相交。

如果线段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;}




0 0
原创粉丝点击