//昨天的比赛题,,一直往凸包那里想了。。看了别人的思路才懂得。。自己的太笨了。。

//任意选取两个水果,并选出水果上两个端点组成一条直线去切割其他的水果,就是判断直线与线段是否相交(n^3*k^3)
//经验:一个方法想不通之后要换别的方法想想。。要有发散的思维。。
#include <iostream>
using namespace std;
struct Point
{
 int x;
 int y;
};
struct fruit
{
 Point point[11];
 int k;
};
fruit Fruit[15];

int judge(Point p1,Point p2,Point p3,Point p4))//线段端点为p1,p2,直线上两点p3,p4
{
 Point tp1,tp2,tp3;
 tp1.x=p1.x-p3.x;
 tp1.y=p1.y-p3.y;
 tp2.x=p4.x-p3.x;
 tp2.y=p4.y-p3.y;
 tp3.x=p2.x-p3.x;
 tp3.y=p2.y-p3.y;
 if((tp1.x*tp2.y-tp1.y*tp2.x)*(tp2.x*tp3.y-tp2.y*tp3.x)>=0)
  return 1;
 else
  return 0;
}
int main()
{
 int t,n,i,j,h,g,q,p;
 cin>>t;
 int cas=0;
 while(t--)
 {
  cas++;
  cin>>n;
  for(i=0;i<n;i++)
  {
   cin>>Fruit[i].k;
   for(j=0;j<Fruit[i].k;j++)
   {
    cin>>Fruit[i].point[j].x>>Fruit[i].point[j].y;
   }
  }
  printf("Case %d: ",cas);
  if(n==1)
  {
   printf("1\n");
   continue;
  }
  int ans=0;
  int max=-1;
  for(i=0;i<n;i++)//前面两个for是枚举每两个水果
   for(j=i+1;j<n;j++)
    for(g=0;g<Fruit[i].k;g++)//这两是枚举两个水果上的点。。
     for(h=0;h<Fruit[j].k;h++)
     {
      ans=2;
      for(q=0;q<n;q++)//然后再枚举其他水果的线段,和那条直线判断
      {
       if(q==i||q==j)
        continue;
       for(p=0;p<Fruit[q].k-1;p++)
       {
        if(judge(Fruit[q].point[p],Fruit[q].point[p+1],Fruit[i].point[g],Fruit[j].point[h]))
        {
         ans++;
         break;
         //有一个交点就直接break;
        }
       }
      }
      if(max<ans)
       max=ans;
      
     }
     cout<<max<<endl;
 }
 return 0;
}

posted on 2011-08-19 10:24  →木头←  阅读(281)  评论(0编辑  收藏  举报