HDU 3952 2011阿里巴巴程序设计公开赛

来源:互联网 发布:淘宝无线产品链接 编辑:程序博客网 时间:2024/06/02 18:24

                这个是2011阿里巴巴程序设计公开赛中的一个题,我们用这套题打了一场组队赛,最后却输在了这个题上,其实看了解题报告http://hi.baidu.com/kerrynit/item/85c865090210ed0aebfe3872很好做,只是比赛时不容易证明这个思路。

摘自解题报告:

1002 Fruit Ninja

类型:几何(简单)

假设有一条线穿过一些水果,那么我们将这条线平移,使之与一水果的一个点相交,然后按这个点进行旋转,又可以使之与另一水果的一个点相交.这次这条线还是穿过这些水果.

所以,我们可以枚举两两水果的点做直线,然后计算该线穿过水果的个数

数据规模很小,随意随便搞.复杂度O(n^3*k^3).

#include<cstdio>#include<cstring>#include<iostream>#define INF 0x7fffffffusing namespace std;struct POINT{    int x,y;};struct shape{    int p;    POINT point[11];};shape sh[11];int n;int check(int k,int i,int j,int h,int m){    int ans=0;    if(k==INF)    {        for(int a=0; a<n; a++)        {            if(a==i||a==h)  continue;            int flags=0,flagx=0;            for(int c=0; c<sh[a].p; c++)            {                if(sh[a].point[c].x<sh[i].point[j].x)                    flags=1;                else     if(sh[a].point[c].x>sh[i].point[j].x)                    flagx=1;                else     if(sh[a].point[c].x==sh[i].point[j].x)                    flags=flagx=1;                if(flags==1&&flagx==1)                {                    ans++;                    break;                }            }        }        return ans;    }    double b=sh[i].point[j].y-k*sh[i].point[j].x;    for(int a=0; a<n; a++)    {        if(a==i||a==h)   continue;        int flags=0,flagx=0;        for(int c=0; c<sh[a].p; c++)        {            double f=k*sh[a].point[c].x+b-sh[a].point[c].y;            if(flags==1&&flagx==1)            {                ans++;                break;            }            if(f>-1e-12&&f<1e-12)            {                flags=flagx=1;            }            else  if(f>-1e-12)                flags=1;            else   if(f<1e-12)                flagx=1;        }    }    return ans;}int main(){   // freopen("in.txt","r",stdin);    int CASE,k;    cin>>CASE;    for(int cas=1; cas<=CASE; cas++)    {        cin>>n;        for(int i=0; i<n; i++)        {            cin>>k;            sh[i].p=k;            for(int j=0; j<k; j++)            {                int a,b;                cin>>a>>b;                sh[i].point[j].x=a,sh[i].point[j].y=b;            }        }        int  maxx=0;        for(int i=0; i<n; i++)        {            for(int j=0; j<sh[i].p; j++)            {                for(int h=i+1; h<n; h++)                {                    for(int m=0; m<sh[h].p; m++)                    {                        double x;                        if(sh[i].point[j].x==sh[h].point[m].x)                            x=INF;                        else                            x=(sh[i].point[j].y-sh[h].point[m].y)*1.0/(sh[i].point[j].x-sh[h].point[m].x);                        int ans=check(x,i,j,h,m);                        if(ans>maxx)                        {                            maxx=ans;                        }                    }                }            }        }        if(n<3)            cout<<"Case "<<cas<<": "<<n<<endl;        else            cout<<"Case "<<cas<<": "<<maxx+2<<endl;    }    return 0;}