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"

Project Euler 102:Triangle containment 包含原点的三角形的更多相关文章

  1. Python练习题 040:Project Euler 012:有超过500个因子的三角形数

    本题来自 Project Euler 第12题:https://projecteuler.net/problem=12 # Project Euler: Problem 12: Highly divi ...

  2. [project euler] program 4

    上一次接触 project euler 还是2011年的事情,做了前三道题,后来被第四题卡住了,前面几题的代码也没有保留下来. 今天试着暴力破解了一下,代码如下: (我大概是第 172,719 个解出 ...

  3. Python练习题 029:Project Euler 001:3和5的倍数

    开始做 Project Euler 的练习题.网站上总共有565题,真是个大题库啊! # Project Euler, Problem 1: Multiples of 3 and 5 # If we ...

  4. Project Euler 9

    题意:三个正整数a + b + c = 1000,a*a + b*b = c*c.求a*b*c. 解法:可以暴力枚举,但是也有数学方法. 首先,a,b,c中肯定有至少一个为偶数,否则和不可能为以上两个 ...

  5. Project Euler 44: Find the smallest pair of pentagonal numbers whose sum and difference is pentagonal.

    In Problem 42 we dealt with triangular problems, in Problem 44 of Project Euler we deal with pentago ...

  6. project euler 169

    project euler 169 题目链接:https://projecteuler.net/problem=169 参考题解:http://tieba.baidu.com/p/2738022069 ...

  7. 【Project Euler 8】Largest product in a series

    题目要求是: The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × ...

  8. Project Euler 第一题效率分析

    Project Euler: 欧拉计划是一系列挑战数学或者计算机编程问题,解决这些问题需要的不仅仅是数学功底. 启动这一项目的目的在于,为乐于探索的人提供一个钻研其他领域并且学习新知识的平台,将这一平 ...

  9. Python练习题 049:Project Euler 022:姓名分值

    本题来自 Project Euler 第22题:https://projecteuler.net/problem=22 ''' Project Euler: Problem 22: Names sco ...

随机推荐

  1. discuz分类信息地区联动菜单字段

    1 = 河南省 1.1 = 郑州市 1.1.1 = 中原区 1.1.2 = 二七区 1.1.3 = 管城区 1.1.4 = 金水区 1.1.5 = 上街区 1.1.6 = 惠济区 1.1.7 = 巩义 ...

  2. 低噪声APD偏置电路

    低噪声APD偏置电路 APD电源摘要:该电路产生并控制光通信中雪崩光电二极管(APD)的低噪声偏置电压.该可变电压通过控制APD的雪崩增益,优化光纤接收器的灵敏度特性.该电路采用低噪声.固定频率PWM ...

  3. [shell练习]——awk练习题

    1. sed和awk有什么区别? (1)awk:按列(域)操作:sed:按行操作(2)awk:文本处理语言,适合对文本进行抽取处理:sed:非交互式的编辑器,适合对文本进行编辑 2. awk要处理域的 ...

  4. SDOI2016 round1滚粗记

    Day -1 刚刚从HN集训回来,感觉整个人萌萌哒.考前不断立flag——这次我一定会滚粗的,然后设想着滚粗之后文化课先补什么,浑浑噩噩的过了一天,晚上看到CA爷(娘)发了关于cena爆栈的问题,这时 ...

  5. [Android Training视频系列] 8.2 Managing Audio Focus

    视频讲解:http://www.eyeandroid.com/thread-15896-1-1.html 由于很多应用程序都可以播放音频,因此在播放前考虑它们如何交互就显得很重要了,为了避免同时出现多 ...

  6. Valuable site on github

    https://thegrid.io/?utm_source=adwords&utm_medium=cpc&utm_campaign=thegrid-display-english&a ...

  7. java rest框架jersey数组单记录问题解决

    JAVA数据接口采用jersey技术,可以返回xml,json等格式,可以根据客户端请求accept,如:Application/json,Application/xml 来得到不同的接口数据,非常好 ...

  8. jquery,js引入css文件,js引入头尾

    jquery,js引入css文件,js引入头尾 今天在项目中,需要把20多个页面加上头和尾部,头和尾是我写的,所以小师傅把这个工作交给我了. 我开始往里面加,先引入common.css,在body开始 ...

  9. linux系统非ROOT用户80端口不能启动tomcat问题的变通办法——通过Iptables端口转发

    2010-07-17 13:21:42 org.apache.tomcat.util.digester.SetPropertiesRule begin 警告: [SetPropertiesRule]{ ...

  10. 2013ACM/ICPC亚洲区南京站现场赛——题目重现

    GPA http://acm.hdu.edu.cn/showproblem.php?pid=4802 签到题,输入两个表,注意细心点就行了. #include<cstdio> #inclu ...