zoukankan      html  css  js  c++  java
  • Project Euler 102:Triangle containment 包含原点的三角形

    Triangle containment

    Three distinct points are plotted at random on a Cartesian plane, for which -1000 ≤ x, y ≤ 1000, such that a triangle is formed.

    Consider the following two triangles:

    A(-340,495), B(-153,-910), C(835,-947)
    X(-175,41), Y(-421,-714), Z(574,-645)

    It can be verified that triangle ABC contains the origin, whereas triangle XYZ does not.

    Using triangles.txt (right click and ‘Save Link/Target As…’), a 27K text file containing the co-ordinates of one thousand “random” triangles, find the number of triangles for which the interior contains the origin.

    NOTE: The first two examples in the file represent the triangles in the example given above.


    包含原点的三角形

    从笛卡尔平面中随机选择三个不同的点,其坐标均满足-1000 ≤ x, y ≤ 1000,这三个点构成一个三角形。

    考虑下面两个三角形:

    A(-340,495), B(-153,-910), C(835,-947)
    X(-175,41), Y(-421,-714), Z(574,-645)

    可以验证三角形ABC包含原点,而三角形XYZ不包含原点。

    在27K的文本文件triangles.txt(右击并选择“目标另存为……”)中包含了一千个“随机”三角形的坐标,找出其中包含原点在其内部的三角形的数量。

    注意:文件中的前两个三角形就是上述样例。

    解题

    考虑了一下原点在三角形内部的三角形,原点到两个边的夹角应该有两个钝角,但是发现结果是510,表示不对,我是根据余弦定理就得costheta 这里有问题在实际中可能出现多于90度的情况然而在我计算中,我不知道怎么判断。还有个问题就是不知道我的这个想法是否有问题,下面的程序是不对的,留在这里待更改。

    package Level4;
    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.ArrayList;
    
    
    public class PE0102{
        public static void run(){
            int count = 0;
            ArrayList<int[]> list = readData();
            for(int i=0;i<list.size();i++){
                int arr[] = list.get(i);
                if(iscontainmentTriangle(arr)){
                    count+=1;
                }
                if(i<10)
                System.out.println(iscontainmentTriangle(arr));
            }
            System.out.println(count);
            
        }
        // 判断原点是否在三角形内部
        public static boolean iscontainmentTriangle(int[] arr){
            int count =0;
            for(int i=0;i<arr.length-1;i+=2){
                int x1 = arr[i];
                int y1 = arr[i+1];
                for(int j=i+2;j<arr.length-1;j+=2){
                    int x2 = arr[j];
                    int y2 = arr[j+1];
                    if(isObtuseAngle(x1,y1,x2,y2))
                        count ++;
                        if(count ==2)
                        return true;
                }
            }
            return false;
        }
        
        // 是不是钝角
        public static boolean isObtuseAngle(int x1,int y1,int x2,int y2){
            long costheta = x1*y1 + x2*y2;
            if(costheta <0)
                return true;
            return false;
        }
        // 转换成整型数组
        public static int [] StringtoInt(String[] strArr){
            int[] IntArr = new int[strArr.length];
            for(int i=0;i<strArr.length;i++)
                IntArr[i] = Integer.parseInt(strArr[i]);
            return IntArr;
        }
        // 读取数据
        public static ArrayList<int[]> readData(){
            String filename= "src/Level4/p102_triangles.txt";
            ArrayList<int[]> list = new ArrayList<int[]>();
            try {
                BufferedReader bufferedReader = new BufferedReader(new FileReader(filename));
                String line = "";
                while((line=bufferedReader.readLine())!=null){
                    String[] strArr = line.split(",");
                    list.add(StringtoInt(strArr));
                }
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return list;
        }
        public static void main(String[] args){
            long t0 = System.currentTimeMillis();
            run();
            long t1 = System.currentTimeMillis();
            long t = t1 - t0;
            System.out.println("running time="+t/1000+"s"+t%1000+"ms");
    
        }
    }
    Java Code

    mathblog 中提到了根据三角形面积相等的方式求解,ABC = ABO + ACO +BCO

    这里我们知道了三角形的三个点如何根据这三个点求面积,看了下面求解的方式,根据两个向量可以快速的求出向量所组成三角形的面积S= 向量交叉相乘差的绝对值的二分之一

    wiki 中有说明

    Java

    package Level4;
    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.ArrayList;
    
    
    public class PE0102{
        public static void run(){
            int count = 0;
            ArrayList<int[]> list = readData();
            for(int i=0;i<list.size();i++){
                int arr[] = list.get(i);
                if(iscontainmentTria(arr)){
                    count+=1;
                }
                
            }
            System.out.println(count);
    //        228
    //        running time=0s16ms
        }
        // 判断原点是否在三角形内部
            public static boolean iscontainmentTria(int[] arr){
                int area = 0;
                int count =0;
                int X1 = arr[0] - arr[2];
                int Y1 = arr[1] - arr[3];
                int X2 = arr[4] - arr[2];
                int Y2 = arr[5] - arr[3];
                int area2 = area(X1,Y1,X2,Y2);
                for(int i=0;i<arr.length-1;i+=2){
                    int x1 = arr[i];
                    int y1 = arr[i+1];
                    for(int j=i+2;j<arr.length-1;j+=2){
                        int x2 = arr[j];
                        int y2 = arr[j+1];
                        area +=area(x1,y1,x2,y2);
                    }
                }
                if(area == area2)
                    return true;
                return false;
            }
        // 这里面积的二倍
        public static int area(int X1,int Y1,int X2,int Y2){
            int area = Math.abs(X1*Y2 - X2*Y1);
            return area;
        }
        // 转换成整型数组
        public static int [] StringtoInt(String[] strArr){
            int[] IntArr = new int[strArr.length];
            for(int i=0;i<strArr.length;i++)
                IntArr[i] = Integer.parseInt(strArr[i]);
            return IntArr;
        }
        // 读取数据
        public static ArrayList<int[]> readData(){
            String filename= "src/Level4/p102_triangles.txt";
            ArrayList<int[]> list = new ArrayList<int[]>();
            try {
                BufferedReader bufferedReader = new BufferedReader(new FileReader(filename));
                String line = "";
                while((line=bufferedReader.readLine())!=null){
                    String[] strArr = line.split(",");
                    list.add(StringtoInt(strArr));
                }
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return list;
        }
        public static void main(String[] args){
            long t0 = System.currentTimeMillis();
            run();
            long t1 = System.currentTimeMillis();
            long t = t1 - t0;
            System.out.println("running time="+t/1000+"s"+t%1000+"ms");
        }
    }

     Python

    # coding=gbk
    
    import time as time 
    import re 
    import math
    import numpy as np 
    def run():
        filename = 'E:/java/projecteuler/src/Level4/p102_triangles.txt'
        mat = readData(filename)
        mat = np.array(mat)
        count = 0
        for line in mat:
            if isContainmentTraingle(line):
                count+=1
        print count 
        
    def isContainmentTraingle(triangle):
        X1 = triangle[0] - triangle[2]
        Y1 = triangle[1] - triangle[3]
        X2 = triangle[4] - triangle[2]
        Y2 = triangle[5] - triangle[3]
        S = area(X1,Y1,X2,Y2)
        for i in range(0,4,2):
            for j in range(i+2,5,2):
                S -= area(triangle[i],triangle[i+1],triangle[j],triangle[j+1])
        return S == 0
        
    def area(x1,y1,x2,y2):
        S = np.abs(x1*y2 - x2*y1)
        return S
        
    def readData(filename):
        mat = list()
        file = open(filename)
        for line in file:
            row = line.split(',')
            row = [int(x) for x in row]
            mat.append(row)
        return mat 
            
    t0 = time.time()
    run() 
    t1 = time.time()
    print "running time=",(t1-t0),"s"
    
    
                
  • 相关阅读:
    VysorPro助手
    Play 2D games on Pixel running Android Nougat (N7.1.2) with Daydream View VR headset
    Play 2D games on Nexus 6P running Android N7.1.1 with Daydream View VR headset
    Native SBS for Android
    ADB和Fastboot最新版的谷歌官方下载链接
    How do I install Daydream on my phone?
    Daydream Controller手柄数据的解析
    蓝牙BLE传输性能及延迟分析
    VR(虚拟现实)开发资源汇总
    Android(Java)控制GPIO的方法及耗时分析
  • 原文地址:https://www.cnblogs.com/theskulls/p/5137927.html
Copyright © 2011-2022 走看看