HDU 4380 Farmer Greedy

这道题,队长大人说,用bitset&三下就好了。。
然后死在了bitset的分类讨论上了。。

这道题,先看复杂度 100 * 100(所有线段)* 1000 == 1e7;
这样就可以做了
思路就是统计在线段上和下的点数,bitset就是这个作用。。
但是,经过昨晚一晚上的郁闷,其实只要知道每条边的下面的点数就够了。这个思路画画图就出来了。然后wa了,才知道边上的点也算在内。(而且根据自己的尝试发现没有房子和金子在同一点的点)
于是,只要简单的分类讨论就可以,bitset的方法(弱弱的我是觉得不是很适合)。
然后,辉说 用叉积奇快,居然只有78ms。。

这里给出我的做法。。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <bitset>
using namespace std;
const int N = 110;
const int M = 1010;
struct myhouse
{
    int x;
    int y;
    bool operator < (const myhouse & wakaka)const
    {
        if(y == wakaka.y)
        {
            return x < wakaka.x;
        }
        return y < wakaka.y;
    }
}house[N], gold[M];
struct edges
{
    int on;
    int under;
}edge[N * N];
int main()
{
    int n, m;
    int cas = 0;
    while(~scanf("%d%d", &n, &m))
    {
        for(int i = 0 ; i < n ; ++ i)
        {
            scanf("%d%d", &house[i].x ,&house[i].y);
        }
        for(int j = 0 ; j < m ; ++ j)
        {
            scanf("%d%d", &gold[j].x ,&gold[j].y);
        }
        sort(house , house + n);//这一步少了很多分类。。
        memset(edge , 0 ,sizeof(edge));
        for(int i = 0 ;i < n ; ++ i)
        {
            for(int j = i + 1; j < n ; ++ j)
            {
                for(int k = 0 ; k < m ; ++ k)
                {
                    if(house[i].x == house[j].x)
                    {
                        if(gold[k].x == house[i].x)
                        {
                            if(gold[k].y < house[i].y)
                            {
                                edge[i * n + j].under ++;
                            }
                            else if(gold[k].y < house[j].y)
                            {
                                edge[i * n + j].on ++;
                            }
                        }
                    }
                    else if(gold[k].x <= max(house[i].x, house[j].x) && gold[k].x >= min(house[i].x ,house[j].x))
                    {
                        double test;
                        if(house[j].x > house[i].x)
                            test = (double)(house[j].y - house[i].y) / (house[j].x - house[i].x) * (gold[k].x - house[i].x)+ house[i].y;
                        else
                            test = (double)(house[j].y - house[i].y) / (house[j].x - house[i].x) * (gold[k].x - house[j].x)+ house[j].y;
                        if(test > gold[k].y)
                        {
                            edge[i * n + j].under ++;
                        }
                        else if(test == gold[k].y)
                        {
                            edge[i * n + j].on ++;
                        }
                    }

                }
            }
        }
        int test;
        int ans = 0;
        for(int i = 0 ; i < n ; ++ i)
        {
            for(int j = i + 1 ; j < n ; ++ j)
            {
                for(int k = j + 1 ; k < n ; ++ k)
                {
                    if(house[i].x == house[k].x)
                    {
                        test = edge[j * n + k].under - edge[i * n + j].under + edge[j * n + k].on;
                    }
                    else if(house[j].x == house[k].x)
                    {
                        test = edge[i * n + k].under - edge[i * n + j].under + edge[i * n + k].on;
                    }
                    else
                    {
                        test = edge[i * n + k].under + edge[j * n + k].under - edge[i * n + j].under + edge[i * n + k].on +edge[j * n + k].on + edge[i * n + j].on;
                    }
                    if(test & 1)
                        ++ ans;
                }
            }
        }
        printf("Case %d: %d\n", ++ cas, ans);
    }

    return 0;
}

你可能感兴趣的:(数学,HDU,多校赛)