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

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

摘自解题报告:

1002 Fruit Ninja

类型:几何(简单)

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

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

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

#include<cstdio>
#include<cstring>
#include<iostream>
#define INF 0x7fffffff
using 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;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值