阿里笔试题-城堡问题

这个题目我两次笔试都遇到了,贴出来纪念一下吧。。。欢迎指正
【8月22:发现有问题,需要重新修改】

将军大胜归来, 夺取很多城堡(xi, yi)。国王向将军许诺, 你站在任意的城堡上, 选择任意角度,看得见的城堡都是你的,包括你站的城堡,但头不能动但。而且不能站在城堡构成的凸集点上。 将军的视角刚好小于180度(无限接近180度), 可以看得无限远。 请帮忙计算出将军最多能得到多少城堡。如果所有的城堡都在凸集点上,那么将军一个城堡也得不到。
输入范例:
10
1
1
-1
1
-1
-1
1
-1
0
0
输出范例:
3

/**
 * Created by MKD on 2017/8/21.
 * 思路是不断的利用两个点连线,获取能够取得的最大点,并排除凸点情况
 */
import java.util.*;
public class Main {
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        int res;
        int _points_size = 0;
        _points_size = Integer.parseInt(in.nextLine().trim());
        double[] _points = new double[_points_size];
        double _points_item;
        for(int _points_i = 0; _points_i < _points_size; _points_i++) {
            _points_item = Double.parseDouble(in.nextLine().trim());
            _points[_points_i] = _points_item;
        }
        res = castle(_points);
        System.out.println(String.valueOf(res));
    }
    static int castle(double[] points) {
        int len = points.length;
        int result = 0;
        if(len<=8) return 0;
        else{
            for (int j=0;j<len/2 ;j++){
                double x1 = points[2*j];
                double y1 = points[2*j+1];
                for(int k=0;k<len/2;k++){
                    if(k==j) continue;
                    double x2 = points[2*k];
                    double y2 = points[2*k+1];
                    double w= getw(x1,y1,x2,y2);
                    double b = getb(x1,y1,x2,y2);
                    int r= getMax(j,k,len,w,b,points);
                    if(r>result) result=r;
                }
            }
        }
        return result;
    }

    public static Double getw(double x1, double y1, double x2, double y2){//计算w
        double w = (x1-x2)/(y1-y2);
        return w;
    }
    public static Double getb(double x1, double y1, double x2, double y2){//计算b
        double w = (x1-x2)/(y1-y2);
        double b = y1 - x1*w;
        return b;
    }
    public static int getMax(int j,int k,int len,double w,double b,double[] points){//寻找最多的城堡
        int n0=0;int n1=0;int n2=0;
        int result=0;
        for(int i=0;i<len/2;i++) {
            if (i == j || i == k) continue;
            double x = points[2 * i];
            double y = points[2 * i + 1];
            double re = y - w * x + b;
            if (re > 0) n1 = n1 + 1;
            else if (re < 0) n2 = n2 + 1;
            else n0 = n0 + 1;
        }
        result = Math.max((n0+n1),(n2+n0));
        if(result == len/2 - 2) return 0;//如果加上连线上除开连接的两个点,数量为total-2,那么一定是凸点
        else return result+1;//排除凸点后,总数再加上本身点,固 + 1
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值