project euler 102

Problem 102


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(右击并选择“目标另存为……”)中包含了一千个“随机”三角形的坐标,找出其中包含原点在其内部的三角形的数量。

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

package projecteuler;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import junit.framework.TestCase;

public class Prj102 extends TestCase {

	public static final String PATH = "E:\\whua\\mathWorkspace\\test_jgraph\\src\\projecteuler\\Prj102.txt";

	public void test() {

		int count = 0;
		List<List<int[]>> dataList = readDatas();
		for (int i = 0; i < dataList.size(); i++) {
			List<int[]> xys = dataList.get(i);
			
			if( isInRegion(xys.get(0), xys.get(1), 0, 0)){
				count ++;
			}

		}
		System.out.println("count=" + count);
	}

	boolean isInRegion(int[] xs, int[] ys, int x, int y) {

		int x1 = xs[0] - 0;
		int x2 = xs[1] - 0;
		int x3 = xs[2] - 0;
		int y1 = ys[0] - 0;
		int y2 = ys[1] - 0;
		int y3 = ys[2] - 0;

		double ab = crossProduct(x1, y1, x2, y2);
		double bc = crossProduct(x2, y2, x3, y3);
		double ca = crossProduct(x3, y3, x1, y1);

		return Math.signum(ab) == Math.signum(bc)
				&& Math.signum(ab) == Math.signum(ca);
	}

	double crossProduct(int x1, int y1, int x2, int y2) {
		return x1 * y2 - y1 * x2;
	}

	List<List<int[]>> readDatas() {
		List<List<int[]>> ret = new ArrayList<List<int[]>>();
		try {

			BufferedReader reader = new BufferedReader(new InputStreamReader(
					new FileInputStream(PATH), "utf8"));
			String str = "";
			while ((str = reader.readLine()) != null) {
				String[] strs = str.split(",");
				int[] xs = new int[3];
				int[] ys = new int[3];

				xs[0] = Integer.parseInt(strs[0]);
				xs[1] = Integer.parseInt(strs[2]);
				xs[2] = Integer.parseInt(strs[4]);
				ys[0] = Integer.parseInt(strs[1]);
				ys[1] = Integer.parseInt(strs[3]);
				ys[2] = Integer.parseInt(strs[5]);

				List<int[]> os = new ArrayList<int[]>();
				os.add(xs);
				os.add(ys);

				ret.add(os);
			}

			reader.close();

		} catch (Exception ex) {
			ex.printStackTrace();
		}

		return ret;

	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值