Topcoder SRM 727 TwoDiagonals

2 篇文章 0 订阅
1 篇文章 0 订阅

Topcoder SRM 727 TwoDiagonals

题目原文

Bearland can be represented as a horizontal plane with N distinct points, denoting positions of N cities.The i-th city has coordinates (x[i], y[i]).


Limak is planning to build two infinitely long roads in Bearland.One should go northwest, and the other should go northeast (both these directions are tilted exactly 45 degrees from the vertical direction).It implies that the two roads are perpendicular to each other, and that they have an intersection point (this point can be a city but not necessarily).


Roads increase the trade significantly.A city will be happy if it lies on at least one of the two roads.Help Limak and find the maximum possible number of happy cities.

    • x { 1, 4, 4, 5 }
    • y { 3, 0, 2, 3 }
    Returns 4
    There are four cities: (1,3), (4,0), (4,2), (5,3).It's possible to draw two lines in such a way that all cities will be happy:
    • x { 0, 1, 2, 3, 4, 5 }
    • y { 2, 2, 2, 2, 2, 2 }
    Returns 2
    The new roads can go through at most two cities in this case.One of many optimal placements is:

题意分析

给定坐标中一些点,在坐标系中画两条相互垂直的先,斜率为正负一,试问如何画这两条线,使得最终在线上的点的个数最多,求出最大点数。

解法分析

因为线的斜率是定的,不同的就是y=x+b中的b了,最开始我想遍历所有b可能的值,存储在其上的点数,后来发现这样的遍历次数无限,因此只需要对每个点计算穿过它的两条线,对于点(x,y),b1=x+y,b2=y-x,建立一个两个map,分别存储斜率不同的两条线,first为不同的b,second为点数,由于交点可能会算重复,因此需要计算两条线的交点是否在所给点集合中,注意这里计算的交点可能是浮点数,而点集中的点都是整点。C++代码如下:

int maxPoints(vector<int> x, vector<int> y) {
        map<double,double> neg;
        map<double,double> pos;
        set<pair<double,double>> point;
        int mymax=0;
        int temp;
        for(int i=0;i<x.size();i++){
            neg[x[i]+y[i]]++;
            pos[y[i]-x[i]]++;
            point.insert(make_pair((double)x[i],(double)y[i]));
        }
        for(auto n=neg.begin();n!=neg.end();n++){
            for(auto p=pos.begin();p!=pos.end();p++){
                temp=(int)((*n).second+(*p).second);
                if(point.count(make_pair(((*n).first/2-(*p).first/2),((*p).first/2+(*n).first/2))))
                   temp=temp-1;
                mymax=max(mymax,temp);
            }
        }
        return mymax;
    }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值