SW练习_点的位置_点线关系

https://koitp.org/problem/POSITION_OF_POINT

求最后两个点,是在图形的外面,还是里面

换成了double,依然没有AC,只是从30 / 100提升到了90 / 100

换成BigInteger后AC了

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigInteger;
 
/**
 meng3.wei 2020.04.16
4
1 1
1 3
3 3
3 1
0 0
2 2
 out
 in
 */
public class 点的位置 {
    static int Max_x=0;
    static int Max_y=0;
    public static void main(String[] args) throws  Exception{
        BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
        int N=Integer.parseInt(reader.readLine());
        Point[] points=new Point[N];
        for (int i = 0; i <N ; i++) {
            String[] line=reader.readLine().split(" ");
            int x=Integer.parseInt(line[0]);
            int y=Integer.parseInt(line[1]);
            if(x>Max_x){Max_x=x;}
            if(y>Max_y){Max_y=y;}
            points[i]=new Point(x,y);
        }
 
        String[] line=reader.readLine().split(" ");
        Point A=new Point(Integer.parseInt(line[0]),Integer.parseInt(line[1]));
        line=reader.readLine().split(" ");
        Point B=new Point(Integer.parseInt(line[0]),Integer.parseInt(line[1]));
 
        System.out.println(process(points,A));
        System.out.println(process(points,B));
        reader.close();
 
    }
 
    static String process(Point[] points,Point C){
        String result="out";
 
        int m=0;
        Point D=new Point(Max_x+97,Max_y+99);
        for (int i = 0; i < points.length-1; i++) {
            Point A=points[i];
            Point B=points[i+1];
            if(cross_check(A,B,C,D)==1){
                m++;
            }
        }
        Point A=points[0];
        Point B=points[points.length-1];
        if(cross_check(A,B,C,D)==1){
            m++;
        }
        if(m%2==1){//奇数,点在里面
            result="in";
        }
        return result;
    }
 
    static int cross_check(Point A,Point B,Point C,Point D){
        int abc=direction(A,B,C);
        int abd=direction(A,B,D);
        int cda=direction(C,D,A);
        int cdb=direction(C,D,B);
        if(abc*abd <=0 && cda*cdb<=0){
            //System.out.printf("ABCD相交 %d,%d->%d,%d %d,%d->%d,%d \n",A.x,A.y,B.x,B.y,C.x,C.y,D.x,D.y);
            return 1;
        }else{
            //System.out.printf("ABCD不相交 %d,%d->%d,%d %d,%d->%d,%d \n",A.x,A.y,B.x,B.y,C.x,C.y,D.x,D.y);
            return 0;
        }
 
    }
 
    public static int direction(Point A,Point B,Point C){
        int dxAB=B.x-A.x;
        int dyAB=B.y-A.y;
        int dxAC=C.x-A.x;
        int dyAC=C.y-A.y;
 
        int abc=BigInteger.valueOf(dxAB).multiply(BigInteger.valueOf(dyAC)).compareTo(
                BigInteger.valueOf(dyAB).multiply(BigInteger.valueOf(dxAC))
        );
        if(abc>0){
            return -1;//顺时针
        }else if(abc<0){
            return 1;//逆时针
        }else{
            if(A.x==B.x && A.y==B.y){
                return 0;//A和B在一个点上
            }
            if(BigInteger.valueOf(dxAB).multiply(BigInteger.valueOf(dxAC)).compareTo(BigInteger.ZERO)<0 ||
                    BigInteger.valueOf(dyAB).multiply(BigInteger.valueOf(dyAC)).compareTo(BigInteger.ZERO)<0
            ){
                return -1;//A在BC的中间,也就是AB和AC刚好接在一起
            }else if(
                    BigInteger.valueOf(dxAB).multiply(BigInteger.valueOf(dxAB))
                            .add(
                                    BigInteger.valueOf(dyAB).multiply(BigInteger.valueOf(dyAB))).compareTo(
                            BigInteger.valueOf(dxAC).multiply(BigInteger.valueOf(dxAC)).add(
                                    BigInteger.valueOf(dyAC).multiply(BigInteger.valueOf(dyAC)))
                    )>=0
            ){//C在AB的中间
                return 0;
            }else {
                return -1;
            }
 
        }
 
 
    }
 
    static class Point{
        int x;
        int y;
 
        public Point(int parseInt, int parseInt1) {
            this.x=parseInt;
            this.y=parseInt1;
        }
    }
}

 

别人AC的代码,没看懂,mark一下

#include <cstdio>
#include <vector>
#define maxfunc(a,b)(a>b?a:b)
#define minfunc(a,b)(a<b?a:b)
  
using namespace std;
  
typedef struct point{
    long x, y;
}Point;
  
typedef struct poligon{
    int ptNums;
    Point *ptlst;
}Poligon;
int n,cas;
int main(){
    vector<Point> vpt;
    vpt.reserve(100001);
    scanf("%d", &n);
    for (int i = 0; i < n; i++){
        Point p;
         
        scanf("%ld%ld", &p.x, &p.y);
     
        vpt.push_back(p);
    }
    Poligon pol;
    pol.ptNums = n;
    pol.ptlst = &vpt[0];
  
    Point testpt;
    cas = 0;
    while (scanf("%ld%ld", &testpt.x, &testpt.y) == 2)
    {
        int cnt = 0;
        for (int i = 0; i < pol.ptNums; i++){
            long x1, x2, y1, y2;
            double tx, t;
            x1 = pol.ptlst->x, y1 = pol.ptlst->y;
             
            if (i == (n - 1)){
                // next point is first point(0) if current is n-1
                pol.ptlst -= (n - 1);
            }
            else pol.ptlst++; // go next point 
            x2 = pol.ptlst->x, y2 = pol.ptlst->y;
            //tmp1 = maxfunc(y1, y2);
  
            if (testpt.y >= maxfunc(y1, y2) || testpt.y <= minfunc(y1, y2)) continue;
            t = (double)(testpt.y - y2) / (y1 - y2);
            // tx is the cross point
            tx = (double)x2 - t*(x2 - x1);
            // only count the point at left of tx
            if (testpt.x < tx) cnt++;
        }
        printf("%s\n", cnt % 2 == 0 ? "out" : "in");
        if(++cas>1) break;
    }
    return 0;
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值