Right triangles with integer coordinates

The points P (x1, y1) and Q (x2, y2) are plotted at integer co-ordinates and are joined to the origin, O(0,0), to form ΔOPQ.

There are exactly fourteen triangles containing a right angle that can be formed when each co-ordinate lies between 0 and 2 inclusive; that is,0 ≤ x1, y1, x2, y2 ≤ 2.

Given that 0 ≤ x1, y1, x2, y2 ≤ 50, how many right triangles can be formed?


格点直角三角形

点P(x1, y1)和点Q(x2, y2)都是格点,并与原点O(0,0)构成ΔOPQ。

当点P和点Q的所有坐标都在0到2之间,也就是说0 ≤ x1, y1, x2, y2 ≤ 2时,恰好能构造出14个直角三角形。

如果0 ≤ x1, y1, x2, y2 ≤ 50,能构造出多少个直角三角形?

 解题

先网上找到的答案,然后看题解中,前面几题给出了暴露的方法,遍历所有的点 ,判断是否是直角三角形就好了,最后的结果要除以2,,因为两个点是可以互换的。

Java

package Level3;

public class PE091{
static void run(){
int N = 50;
int count = 0;
// 第一个顶点
for(int x1 = 0; x1<=N;x1++){
for(int y1 = 0;y1<=N ;y1++){
if(x1==0 && y1==0) continue;
// 第二个顶点
for(int x2 = 0;x2<=N;x2++){
for(int y2=0;y2<=N;y2++){
if(x2==0&&y2==0 || x1==x2&&y1==y2)
continue;
//判断是否是三角形
double d1 = getDistance(0,0,x1,y1);
double d2 = getDistance(0,0,x2,y2);
double d3 = getDistance(x1,y1,x2,y2);
if(d1+d2==d3|| d1+d3==d2||d2+d3==d1)
count++;
}
}
}
}
System.out.println(count/2);
}
// 14234
// running time=0s71ms
static double getDistance(int x1,int y1,int x2,int y2){
double d1 = (x1-x2)*(x1-x2);
double d2 = (y1-y2)*(y1-y2);
return d1+d2;
} 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"); }
}

参考链接1  参考链接2

上面给出来很好的不用暴力的方法

对于直角在原点的情况:

P Q两点只能在x轴  y轴上,固定一点看另一点,显然有50中可能,然而这一点也有50种可能,共2500种

对于直角在x轴或者y轴的情况:

当P 在x轴上的某点时候,Q的x坐标显然要和P 的一样,PQ都各有50个位置,共2500种

当P 在y轴的时候,也有2500种

对于直角在方格内部的时候:

要使得是直角三角形:OP要垂直PQ

OP的斜率:k = dy/dx  (dy/dx是最简分数)    其中P的坐标设为(x,y)

则PQ的斜率是:-dx/dy

如何根据斜率,找到Q的整数点,或者Q点的个数。

当P点的y轴值>Q点的y轴的值时候:

(如上图所示)可以发现:Q1 Q2 把PQ3等分成三份。三个Q点都是整数点。

对斜率为k = dy/dx :可以通过一个dy * dx的方格表示出来,所以,对于P(x,y)点,x每加一个dx y每减一个dy都是一个整数Q点,那么有多少个符合要求的点?只需要看最大能走多少步,

对于PQ的斜率是dx/dy,当P(x,y),   对x而言最大的步数是:(N-x)/dy ,对y而言最大的步数是:y/dx

这样其最小值就是Q的整数点数:MIN((N-x)/dy,y/dx)

当P点的y轴值<Q点的y轴的值时候:


PQ的斜率是:-dx/dy

P(x,y) x向左走的最大步数:x/dy y向上走的最大步数:(N-y)/dx

这样其最小值就是Q的整数点数:MIN(x/dy,(N-y)/dx)

这与上面链接的结果不一样,根据运行结果发现答案是一样的

其实吧 对于P点的坐标可以是在N*N方格中的任意一点,P的坐标是可以对称的,所以可以直接乘以二的。

JAVA

package Level3;

public class PE091{
static void run1(){
int N = 50;
// 直角在原点,直角在x轴 直角在y轴,个数都是N*N
int result =N*N*3;
//下面只需要对直角在方格内部的情况
for(int x = 1;x<= N;x++){
for(int y=1;y<= N;y++){
int fact = gcd(x,y);
result += Math.min(y*fact/x, (N-x)*fact/y);
result += Math.min(x*fact/y, (N-y)*fact/x);
}
}
System.out.println(result);
}
// 14234
// running time=0s78ms
static int gcd(int x,int y){
if(x<y){
int tmp = x;
x = y;
y = tmp;
}
int r = x%y;
while(r!=0){
int tmp =x;
x = y;
y = tmp%x;
r = x%y;
}
return y;
}
static void run(){
int N = 50;
int count = 0;
// 第一个顶点
for(int x1 = 0; x1<=N;x1++){
for(int y1 = 0;y1<=N ;y1++){
if(x1==0 && y1==0) continue;
// 第二个顶点
for(int x2 = 0;x2<=N;x2++){
for(int y2=0;y2<=N;y2++){
if(x2==0&&y2==0 || x1==x2&&y1==y2)
continue;
//判断是否是三角形
double d1 = getDistance(0,0,x1,y1);
double d2 = getDistance(0,0,x2,y2);
double d3 = getDistance(x1,y1,x2,y2);
if(d1+d2==d3|| d1+d3==d2||d2+d3==d1)
count++;
}
}
}
}
System.out.println(count/2);
}
// 14234
// running time=0s71ms
static double getDistance(int x1,int y1,int x2,int y2){
double d1 = (x1-x2)*(x1-x2);
double d2 = (y1-y2)*(y1-y2);
return d1+d2;
} 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
from itertools import combinations
def run():
N = 50
count = N*N*3
for x in range(1,N+1):
for y in range(1,N+1):
fact = gcd(x,y)
count += min((N-x)*fact/y,y*fact/x)*2
print count #
# running time= 0.00300002098083 s
def gcd(x,y):
if x<y:
x,y = y,x
while x%y!=0:
tmp = x
x = y
y = tmp%y
return y t0 = time.time()
run()
t1 = time.time()
print "running time=",(t1-t0),"s"

Project Euler 91:Right triangles with integer coordinates 格点直角三角形的更多相关文章

  1. [project euler] program 4

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

  2. 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 ...

  3. Python练习题 039:Project Euler 011:网格中4个数字的最大乘积

    本题来自 Project Euler 第11题:https://projecteuler.net/problem=11 # Project Euler: Problem 10: Largest pro ...

  4. Python练习题 032:Project Euler 004:最大的回文积

    本题来自 Project Euler 第4题:https://projecteuler.net/problem=4 # Project Euler: Problem 4: Largest palind ...

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

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

  6. Project Euler 9

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

  7. project euler 169

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

  8. 【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 × ...

  9. Project Euler 第一题效率分析

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

随机推荐

  1. Linux C 程序 线程(18)

    线程控制 1.线程与进程的关系 线程:计算机中独立运行的最小单位. 在用户角度:多个线程是同时执行的. 操作系统角度:各个线程交替执行 以上只针对单核CPU的情况 在多核CPU主机上,多个线程可以同时 ...

  2. angular这个大梗的学习笔记

    angular定义一个模块(module)及控制器(controller)的局部声明方法: var app=angular.module("Myapp",[]); myapp.co ...

  3. node-mongo-native1.3.19连接mongo的最优方法

    最近需要在node下连接mongo,尝试了很多方法,本文简要总结一下 选择Driver 首先,基本上有4个常见的driver供选择 1.官方的是node-mongo-native 2.基于node-m ...

  4. laravel--has方法--查看关联关系

    has()方法可以用来查询是否有关联关系的一个东西,一般其他的has方法 就是判断这个里面有没有值 $packageOrders = Company::has('packages')->get( ...

  5. 使用VisualSVN Server自动发布站点

    使用VisualSVN Server自动发布站点可以节省大量的发布时间. 适用于项目测试版本 通常一个项目在测试阶段会遇到以下问题 1.开发人员修改缺陷要实时反应到测试环境 2.项目经理想让客户及时看 ...

  6. python操作mysql之pymysql

    pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同.但目前pymysql支持python3.x而后者不支持3.x版本. 本文测试python版本:2.7.11.mys ...

  7. Windows7 sp1 64位下安装配置eclipse+jdk+CDT+minGW

    需要的工具: jdk-7u11-windows-x64.exe  eclipse-SDK-4.2.2-win32-x86_64.zip cdt-master-8.1.2.zip mingw-get-i ...

  8. 【iOS】屏幕旋转,屏幕自适应方向变化

    1. iOS有四个方向的旋转,为了保证自己的代码能够支持旋转,我们必须首先处理一个函数: - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInter ...

  9. centos crontab 定时任务详解

    安装crontab: yum install crontabs 说明: /sbin/service crond start //启动服务 /sbin/service crond stop //关闭服务 ...

  10. OC类的本质,深入探讨,load方法和initialize方法

    1:类的本质:类也是一种类,可以叫做类类,类对象,类类型: 2:类和对象在内存中分配问题(注意区分类的对象和类对象的概念) 类对象在内存中只有一份,且只加载一次,类对象中存放了类中定义的方法: 而成员 ...