출처 : http://euler.synap.co.kr/prob_detail.php?id=39
세 변의 길이가 모두 자연수 {a, b, c}인 직각삼각형의 둘레를 p 로 둘 때, p = 120 을 만족하는 직각삼각형은 아래와 같이 세 개가 있다.
{20, 48, 52}, {24, 45, 51}, {30, 40, 50}
1000 이하의 둘레 p에 대해서, 직각삼각형이 가장 많이 만들어지는 p의 값은 얼마인가?
[Python]
import math
def Star(n):
a = 0
c = 0.0
p =n/2
_list = []
while a < p:
a += 1
for b in range(a,p-a):
c = math.sqrt(a*a + b*b)
if c % 1 == 0:
_list.append( a+b+c )
return max(set(_list),key=_list.count)
print Star(1000)
print Star(10000)
840.0
5040.0
```
2014年05月14日 23:52
포트란입니다 그냥 무식하게 반복문 돌렸습니다
출력은 둘레 840일 때 16가지 입니다만 a, b가 대칭인 경우를 생각해보면 8가지 같습니다
program codingdojo451
integer p, a, b, c, count, mcount, mnum
mcount=0
do p=3, 1000
count=0
do a=1, p-2
do b=1, p-a-1
c=p-a-b
if(a**2 + b**2 .EQ. c**2) then
count=count+1
end if
end do
end do
if(count .GT. mcount) then
mcount=count
mnum=p
end if
end do
print *,mcount,mnum
pause
end program codingdojo451
직각삼각형의 다음과 같은 두가지 법칙을 이용하여 문제를 풀어 보았습니다.
python 2.7
import math
def right_triangle(n):
found = []
count = 0
for a in range(3, n+1, 3):
if a in found: continue
for b in range(1, n+1-a):
c = math.sqrt(a**2+b**2)
if a+b+c == n:
found+=[a,b,c]
count+=1
return count
m = -1
found = -1
for i in range(1, 1001):
v = right_triangle(i)
if v > m:
m = v
found = i
print found, m
대략 30초정도 걸리네요. 더 좋은 알고리즘을 연구해 봐야 할 것 같습니다.
2014年05月14日 11:18
세 변의 길이를 a,b,c라 하고 둘레를 p라 하면 a^2+b^2 = c a+b+c = p
이로부터 c = p-a-b이므로 a^2+b^2 = (p-a-b)
그런데 a^2+b^2 = ((a+b)^2 + (a-b)^2)/2
이로부터 2c^2 = (a+b)^2 + (a-b)^2 = (p-c)^2 + (p-c-2b)^2 이 식을 정리하면 c = - (2b^2 - 2bp - p^2) / (2b-2p)
a+b = p-c에 위의 c를 대입하면 a+b = (p^2 - 2b^2) / (2p-2b) b를 우변으로 이항하면 a = p(2b-p) / 2(b-p)
따라서 a,b,c를 모두 p와 b의 식으로 나타낼 수 있음.
따라서 루프는 p와 b에 대해서 두개만 돌리면 됨.
#include <stdio.h>
int main(void) {
int p;
int a, b, c;
int max_p[2]={-1, -1};
for(p=3; p <= 1000; ++p){
int cnt = 0;
for(b = p-1; b >= 0; --b){
c = - ((2*b*b) - 2*(b*p) + p*p) / (2*(b - p));
a = p*(2*b-p)/(2*(b-p));
if(a > b) break;
if(a>0 && c>0 && a+b+c == p){
cnt++;
}
}
if(cnt > max_p[1]) {
max_p[0] = p;
max_p[1] = cnt;
}
}
printf("%d\n", max_p[0]);
return 0;
}
[Python 2.7.3] 위에 좋은 알고리즘이 많아 약간 무식(?) 하지만 적절히 loop를 최소화하는 방법을 써보았습니다. 빗변 c는 a,b보다 작지않으며, 닮은꼴 삼각형을 배제시키기위해서 b 가 a보다 클때만 연산을 수행하면 중복 연산을 피할 수 있다고 생각했습니다. a+b+c가 1000 이상이면 c를 더 이상 진행 시킬 필요가 없고, b,c의 loop 시작 index를 아래 코드처럼 정의하면1000^3 보다는 훨씬 적은 횟수로 돌 수 있네요.
pp = [0]*1001
for a in range(1,1000) :
for b in range(a,1000) :
for c in range(b,1000) :
_sum = a+b+c
if _sum <= 1000 :
if (c*c)==(a*a+b*b) :
temp = pp[_sum]
pp[_sum] = temp+1
print "a,b,c = ",a,b,c
print "pp and sum",pp[a+b+c], a+b+c
else :
break
temp = max(pp)
for i in range(1001) :
if temp==pp[i] :
print i,temp
제 노트북에서 18초 나오네요..
840 8
18.0680000782
2014年06月10日 15:43
C언어로 작성했습니다.
/*
사용한 조건:
a^2 + b^2 = c^2
a + b > c
그리고 a, b, c 중 하나는 반드시 3의 배수다.
여기서 둘레 p = a + b + c라고 한다면,
a^2 + b^2 = (p - a - b)^2
이고, 위의 식을 a에 대해 정리한다면,
a = (2bp - p^2) / 2(b-p) --- (1)
그리고 이 식과 p = a + b + c를 a + b > c에 대입하면
p(2b-p)/2(b-p) > p/2 - b
이고, 이 식을 정리하면
b(2b-p)<0
따라서 유효한 b의 범위는...
0 < b < p/2 --- (2)
그리고 여기서 이대로만 루프를 돌린다면 만일 p = 12인 경우
(a, b, c)의 집합이 (3, 4, 5), (4, 3, 5)가 나와 동일한 삼각형에 대해 중복 연산을 하게 되므로 쓸데없는 루프를 돌게 됩니다.
따라서 저는 a < b라는 조건을 추가했습니다.
a < b
위의 식에 (1) 식을 넣는다면
p(2b-p)/2(b-p) < b
위의 식을 정리하여 b의 범위를 구한다면
(2-2^0.5)p/2 < b < (2+2^0.5)p/2
가 나오는데, 이 때 (2)번 식에서 나타나는 b의 범위와 겹치는 부분만 따진다면
(2-2^0.5)p/2 < b < p/2 -- (3)
이 됩니다.
또한 a, b, c 중 하나는 반드시 3의 배수이므로, 가장 작은 3의 배수인 3을 포함하는 세 정수의 조합은
(3, 4, 5)이므로 p의 가능한 최소값은 3+4+5인 12가 됩니다.
따라서 저는 p는 12부터 1000까지 루프를 돌고, b는 (2-2^0.5)p/2 < b < p/2의 범 위내에서 루프를 돌게 했습니다.
Microsoft Visual Studio 2013로 작성했습니다.
*/
#include <stdio.h>
#include <math.h>
int main(void) {
unsigned int threshold = 0;
printf("Input the threshold : ");
scanf_s("%u", &threshold); // MSVS 2013에서는 scanf를 쓰지 못하게 함.
if (threshold == 0 || threshold < 12) {
printf("Invalid value.");
return -1;
}
unsigned int result[2] = { 0 };
unsigned int loopCount = 0;
float sqrt_2 = (float)sqrt(2);
for (size_t p = 12; p <= threshold; p++) {
size_t b_limit = p / 2;
if (p % 2 != 0) {
b_limit++;
}
float b_limit_lower_llf = (2 - sqrt_2) / 2.0f * (float)p;
size_t b_limit_lower = (size_t)b_limit_lower_llf;
if (b_limit_lower < b_limit_lower_llf) {
b_limit_lower++;
}
unsigned int match_count = 0;
float llf_a = 0;
size_t a = 0;
for (size_t b = b_limit_lower; b < b_limit; b++) {
llf_a = (float)p * (2 * (float)b - (float)p) / (2 * ((float)b - (float)p));
a = (size_t)llf_a;
if (llf_a == a) {
match_count++;
}
loopCount++;
}
if (match_count > result[1]) {
result[0] = p;
result[1] = match_count;
}
}
printf("Circumference with the most right triangles with integer sides = %u\n", result[0]);
printf("Count of created triangles with the conditions = %u\n", result[1]);
printf("Total loop count = %u\n", loopCount);
return 0;
}
/* 수행 결과:
Input the threshold : 1000
Circumference with the most right triangles with integer sides = 840
Count of created triangles with the conditions = 8
Total loop count = 103396
계속하려면 아무 키나 누르십시오 . . .
*/
그래도 약간 마음에 들지 않아 다른 방법을 좀 찾아봤습니다. 이번에는 검색 방법 자체를 다르게 했습니다. 또한 더블 링크드 리스트를 썼기 때문에, C로 짠 버전도 있지만 너무 길어서 생략하고, C++에서 STL 라이브러리를 이용한 버전만 올립니다. 탐색에 사용한 방법은 아래의 링크에 있습니다. http://ko.wikipedia.org/wiki/피타고라스_수
//
// main.cpp
// CodingDoJang-451-CPP
//
// Created by Chrome-MBPR on 7/2/14.
// Copyright (c) 2014 cr2025x1. All rights reserved.
//
#include <iostream>
#include <list>
#include <cmath>
using namespace std;
struct PT {
size_t a;
size_t b;
size_t c;
bool primitive;
};
typedef struct PT PT;
class cPT_pair {
protected:
size_t _p;
list<PT> _pt_List;
public:
const size_t &p;
const list<PT> &pt_List;
cPT_pair() : p(_p), pt_List(_pt_List) {
setP(_p);
}
void setP(size_t p) {
this->_p = p;
}
list<PT>* set_pt_List() {
return &_pt_List;
}
};
class cPT_pair_set : public list<cPT_pair*> {
public:
virtual ~cPT_pair_set() {
for (list<cPT_pair*>::iterator itr = this->begin(); itr != this->end(); advance(itr, 1)) {
delete *itr;
}
}
};
void print_cPTList(list<cPT_pair*>* cPTList, bool primitive_mark);
int main(int argc, const char * argv[])
{
size_t threshold = 0;
cout << "Input the threshold: ";
cin >> threshold;
cout << "Searching primitive Pythagorean triples..." << endl;
cPT_pair_set* cPTList = new cPT_pair_set;
size_t loopCount_1st = 0;
// 짝수인 p만이 자연수인 피타고라스 수의 합이 될 수 있다. (p = 2m^2 + 2mn)
for (size_t p = 12; p <= threshold; p += 2) {
// a^2 + b^2 = c^2이고 서로소인 (a, b, c)는 아래와 같이 m, n을 통해 표현할 수 있다.
// a = m^2 - n^2
// b = 2mn
// c = 2m^2 - n^2
// m>n, m, n은 자연수, m+n은 홀수
//
// p = a + b + c
// = 2m^2 + 2mn
// n = p/(2m) - m
// n은 자연수이므로 p/(2m)-m > 0, 식을 정리하면
// -(p/2)^0.5 < m < (p/2)^0.5
// 또한 m > n이므로 p/(2m)-m < m, 식을 정리하면
// m < -p^0.5/2 or m > p^0.5/2
// 두 범위의 교차부분은 0.5p^0.5 < m < (p/2)^0.5
//
// 즉 m은 저 범위 내에서 루프를 돌린다.
// 이렇게 만들어진 a, b, c는 원시 피타고라스 수가 된다.
// 원시 피타고라스 수: a, b, c의 최대공약수가 1인 피타고라스 수. ex. (3, 4, 5), (5, 12, 13),
size_t m_LowerBound = (size_t)floor((pow(p, 0.5f) / 2.0f));
size_t m_UpperBound = (size_t)ceil(pow(p / 2.0f, 0.5f));
size_t n = 0;
for (size_t m = m_LowerBound + 1; m < m_UpperBound; m++) {
loopCount_1st++;
if (p % (2 * m) != 0) {
// n이 자연수가 될 수 없음.
continue;
}
n = p / (2 * m) - m;
if ((m + n) % 2 == 0) {
// m + n이 홀수가 아니다.
continue;
}
if ((m > 1 && n > 1) && (m % n == 0 || n % m == 0)) {
// m과 n이 서로소가 아니다.
continue;
}
size_t m_2 = m * m;
size_t n_2 = n * n;
size_t a = m_2 - n_2;
size_t b = 2 * m * n;
size_t c = m_2 + n_2;
PT newPT;
newPT.a = a;
newPT.b = b;
newPT.c = c;
newPT.primitive = true;
unsigned char isNewNodeNeeded = 1;
list<cPT_pair*>::iterator lastNode = cPTList->end();
advance(lastNode, -1);
if (cPTList->size() > 0) {
cPT_pair* last_cPT_pair = *lastNode;
if (last_cPT_pair->p == p) {
isNewNodeNeeded = 0;
last_cPT_pair->set_pt_List()->push_back(newPT);
}
}
if (isNewNodeNeeded) {
cPT_pair* new_cPT_pair = new cPT_pair;
new_cPT_pair->setP(p);
new_cPT_pair->set_pt_List()->push_back(newPT);
cPTList->push_back(new_cPT_pair);
}
}
}
// 찾아낸 원시 피타고라수 수들을 출력
cout << "Printing found primitive Pythagorean triples..." << endl;
cout << "p : circumference of the right triangle" << endl;
print_cPTList(cPTList, false);
size_t cPT_pair_listCount = cPTList->size();
cout << "Total count of found p with Pythagorean triples = " << cPT_pair_listCount << endl;
cout << "Total loop count during the search for primitive Pythagorean triples = " << loopCount_1st << endl;
// 원시형이 아닌 피타고라스 수에 대한 탐색
cout << "Searching and adding non-primitive Pythagorean triples..." << endl;
size_t loopCount_2nd = 0;
size_t maxP[2] = { 0 }; // [0] = 현재까지 가장 많은 피타고라스 수를 가지는 p, [1] = [0]에 있는 p가 가진 피타고라스 수 세트의 개수
size_t p_threshold = threshold;
// p의 초기 값을 짝수로 짜맞춘다.
if (p_threshold % 2 != 0) {
p_threshold--;
}
// 위에서 구한 원시 피타고라스 수를 가지고 있는 링크드 어레이에 원시형이 아닌 피타고라스 수들을 추가시킨다.
list<cPT_pair*>::iterator insertionPoint = cPTList->end();
advance(insertionPoint, -1);
size_t foundCount = 0;
for (size_t p = p_threshold; p >= 12; p -= 2) {
foundCount = 0;
// 삽입 지점(insertion point)을 항상 현재 p보다 높은 값과 낮은 값끼리의 경계점에 둔다. 만일 현재 p와 같은 값을 가진 노드가 있다면 그 노드를 삽입지점으로 고르며, 없다면 현재 p보다 작은 값 중 가장 큰 값을 가지는 노드를 고른다.
// 위의 알고리즘 결과로 나오는 리스트의 각 노드의 p는 앞에서 뒤로 오름차순이다.
while ((*insertionPoint)->p > p) {
advance(insertionPoint, -1);
}
// 삽입 지점 노드를 기준으로, 앞쪽을 향해 노드들을 순차적으로 읽어나가 노드의 p값을 비교한다.
// 삽입 지점 노드와 그 앞의 노드들은 모두 모두 원시 피타고라스 수만을 담고 있다.
list<cPT_pair*>::iterator current_cPT_pairNode = insertionPoint;
bool isWritingNodeDecided = false;
list<cPT_pair*>::iterator writingNode;
list<PT>* writingPTList = nullptr;
while (1) {
isWritingNodeDecided = false;
cPT_pair* current_cPT_pair = *current_cPT_pairNode;
loopCount_2nd++;
// 원시 피타고라스 수를 가지는 둘레값이 현재 p값의 약수라면, 현재 p값을 둘레값으로 나눈 값을 원시 피타고라스 수에 곱한다면 현재 p값을 둘레로 가지는 피타고라스 수(원시는 아닌)가 나온다.
if (p % current_cPT_pair->p == 0) {
size_t commonDivisor = p / current_cPT_pair->p;
if (commonDivisor == 1) {
// 1배수다 == 현재 검사 중인 노드의 p값과 현재 p값은 같다. 이 때는 아래의 작업을 할 경우 기존 값과 중복되는 똑같은 값이 추가 저장되므로, 값을 추가 저장하는 아래의 작업을 하면 안 된다.
foundCount++;
}
else {
if (isWritingNodeDecided == false) {
isWritingNodeDecided = true;
// 삽입지점에 현재의 p값을 가진 노드가 있다. 노드를 추가 삽입할 필요성이 없으므로 이 노드를 그대로 활용한다.
if ((*insertionPoint)->p == p) {
writingNode = insertionPoint;
}
else {
// 현재의 p값을 가지는 노드가 없으므로, 노드를 삽입지점의 뒷편에 추가 삽입한다.
cPT_pair* new_cPT_pair = new cPT_pair;
new_cPT_pair->setP(p);
writingNode = insertionPoint;
advance(writingNode, 1);
cPTList->insert(writingNode, new_cPT_pair);
advance(writingNode, -1);
}
writingPTList = (*writingNode)->set_pt_List();
}
// 현재 읽어들인 노드가 가지고 있는 원시 피타고라스 수 세트에 구해둔 배수를 곱해 현재 p값을 둘레로 가지는 비원시 피타고라스 수 세트를 만들어 현재 p값을 가지고 있는 기록 중인 노드의 하위 링크드 리스트에 추가한다.
const list<PT>& currentPTList = current_cPT_pair->pt_List;
for (list<PT>::const_iterator currentPTNode = currentPTList.cbegin();
currentPTNode != currentPTList.cend();
advance(currentPTNode, 1)) {
PT currentPT = *currentPTNode;
PT newPT;
newPT.a = currentPT.a * commonDivisor;
newPT.b = currentPT.b * commonDivisor;
newPT.c = currentPT.c * commonDivisor;
newPT.primitive = 0;
writingPTList->push_back(newPT);
foundCount++;
}
}
}
// 읽어낸 노드의 바로 앞 노드를 지정한다. 위에서 삽입한 노드들은 모두 삽입지점의 뒤에 추가되었다.
// 따라서 그 어떤 루프도 이전 루프에서 추가한 비원시 피타고라스 수가 담긴 노드를 접근하게 되는 비효율적인 경우가 생기지 않는다.
if (current_cPT_pairNode == cPTList->begin()) {
// 맨 앞 노드임을 의미하므로, 현재 p값에 대한 작업을 중지한다.
break;
}
else {
advance(current_cPT_pairNode, -1);
}
}
// 가장 많은 피타고라스 수를 가진 둘레값을 현재 값과 비교해 저장
if (maxP[1] < foundCount) {
maxP[0] = p;
maxP[1] = foundCount;
}
}
cout << "Printing found entire Pythagorean triples..." << endl;
cout << "p : circumference of the right triangle" << endl;
print_cPTList(cPTList, 1);
cout << "Total loop count during the search for all Pythagorean triples = " << loopCount_2nd << endl;
cout << "Circumference P with the most Pythagorean triples = " << maxP[0] << "(" << maxP[1] << " sets)" << endl;
cout << "Total loop during entire operations = " << loopCount_1st + loopCount_2nd << endl;
delete cPTList;
return 0;
}
void print_cPTList(list<cPT_pair*>* cPTList, bool primitive_mark) {
for (list<cPT_pair*>::iterator current_cPT_pairNode = cPTList->begin();
current_cPT_pairNode != cPTList->end();
advance(current_cPT_pairNode, 1)) {
cPT_pair* current_cPT_pair = *current_cPT_pairNode;
const list<PT>& currentPTList = current_cPT_pair->pt_List;
for (list<PT>::const_iterator currentPTNode = currentPTList.cbegin();
currentPTNode != currentPTList.cend();
advance(currentPTNode, 1)) {
cout << "p = " << current_cPT_pair->p << ", (a, b, c) = (" << currentPTNode->a << ", " << currentPTNode->b << ", " << currentPTNode->c << ")";
if (currentPTNode->primitive && primitive_mark) {
cout << " (primitive)";
}
cout << endl;
}
}
}
/*
실행결과:
Input the threshold: 1000
Searching primitive Pythagorean triples...
Printing found primitive Pythagorean triples...
p : circumference of the right triangle
(중략)
Total count of found p with Pythagorean triples = 75
Total loop count during the search for primitive Pythagorean triples = 2169
Searching and adding non-primitive Pythagorean triples...
Printing found entire Pythagorean triples...
p : circumference of the right triangle
(중략)
p = 840, (a, b, c) = (399, 40, 401) (primitive)
p = 840, (a, b, c) = (390, 56, 394)
p = 840, (a, b, c) = (350, 120, 370)
p = 840, (a, b, c) = (252, 240, 348)
p = 840, (a, b, c) = (105, 360, 375)
p = 840, (a, b, c) = (315, 168, 357)
p = 840, (a, b, c) = (140, 336, 364)
p = 840, (a, b, c) = (210, 280, 350)
(중략)
Total loop count during the search for all Pythagorean triples = 18409
Circumference P with the most Pythagorean triples = 840(8 sets)
Total loop during entire operations = 20578
Program ended with exit code: 0
*/
최대한 더블 링크드 리스트의 장점을 살려서 썼습니다. 복사 작업 등을 제외하고 조건에 맞는 숫자를 찾기 위해 도는 루프의 수를 이번에는 20578회로 줄일 수 있었습니다. 2013년 후기형 맥북 프로 레티나 15인치 기준으로 거의 시작 직후에 답이 나오네요.
Xcode 5.1.1로 작성하였습니다.
2014年06月29日 15:06
#python 3.2.5
def calc_c(a, b):
assert(a > 0)
if b < a:
return False
assert(a <= b)
sq = a*a + b*b
sqa = a**a
for c in range(a, sq):
if sq == c*c:
return c
return False
def calc_b(L, a):
numerator = L*L - 2*L*a
if numerator < 0: return False
denominator = 2 * (L - a)
if 0 == numerator % denominator:
return numerator//denominator
return False
def abr(L):
rt = []
hL = (L // 2) * 2
for a in range(1, hL):
b = calc_b(L, a)
if not b: continue
c = calc_c(a, b)
if not c: continue
#yield a
rt.append((a, b, c))
return rt
def main():
rt = dict(len=1, lst=[])
L = 0
for l in range(1, 1001):
tmp = abr(l)
if len(tmp) > L:
L = len(tmp)
rt['len'] = l
rt['lst'] = tmp
print(L, rt['len'], rt['lst'])
'''
8
840
[(40, 399, 401), (56, 390, 394), (105, 360, 375), (120, 350, 370), (140, 336, 364), (168, 315, 357), (210, 280, 350), (240, 252, 348)]
'''
2014年07月01日 19:23
python 2.7.8
angle_tri = list()
def is_angle_tri(length_list):
left_clause = 0
right_clause = 0
max_num = max(length_list)
max_num_index = length_list.index(max_num)
for i in range(3):
if i == max_num_index:
left_clause = length_list[i] ** 2
else:
right_clause += length_list[i] ** 2
if left_clause == right_clause:
return True
return False
def is_duple(length_list):
if set(length_list) in map(set,angle_tri):
return True
return False
maxv = 0
max_n = 0
for n in range(3,1001):
angle_tri = list()
for i in range(1,n+1):
for j in range(1,n+1):
if is_angle_tri([i,j,n-i-j]) and not is_duple([i,j,n-i-j]):
angle_tri.append([i,j,n-i-j])
print n
if maxv < len(angle_tri):
maxv = len(angle_tri)
max_n = n
print 'max = %d' % max_n
1부터 p 까지 i와 j의 이중 반복문을돌려서 계산했습니다. i와 j가 정해졌다면 나머지 한숫자는 자연스럽게 p-i-j 이기때문에 이중반복문을 사용하였습니다. 근데 좀 오래걸리는군요.. 더좋은알고리즘이 분명있을텐데말이죠..흠 생각해봐야겠군요 어쨋든 답은 840입니다.
2014年07月25日 12:54
def tri(abc):
if abc[2]*abc[2] == abc[0]*abc[0] + abc[1]*abc[1] :
return True
else :
return False
def max_tri(num):
data = []
answer = []
for i in range(1, num):
for j in range(i, int(num/2)):
k = num - i - j
data = [i, j, k]
data = sorted(data)
if (tri(data)) & (data not in answer):
answer.append(data)
return len(answer)
max_nm = 0
final = 0
for i in range(3, 1001):
tmp = max_tri(i)
if max_nm < tmp :
max_nm = tmp
final = i
print (final)
2014年08月21日 01:17
Java 사용. 맨위 답이 정말 소름끼치내요.. 많이 배워갑니다. 결과 값 둘레는 840 이며 개수는 8 Roop = 16099676
/*
세 변의 길이가 모두 자연수 {a, b, c}인 직각삼각형의 둘레를 p 로 둘 때, p = 120 을 만족하는 직각삼각형은
아래와 같이 세 개가 있다.
{20, 48, 52}, {24, 45, 51}, {30, 40, 50}
1000 이하의 둘레 p에 대해서, 직각삼각형이 가장 많이 만들어지는 p의 값은 얼마인가?
*/
public class Fifth {
//A^2 + B^2 = C^2
//A+B > C
//A+B+C < 1000
/*
삼각형을 만드는 조건 (A< B <C)
A+B > C 이기 때문에
C+C < A+B+C < C+C+C
@ 2C < A+B+C < 3C 이고 A+B+C = P 이므로
P/3 < C < P/2 이다.
*/
public static void main(String[] args){
int A,B,C,P;
int roopCount = 0;
int resultP = 0;
int resultN = 0;
for(P=3; P< 1000; P++){
int number = 0;
for(C = P/3+1; C < (int)Math.ceil(((double)P/2.0));C=C+1){
for(A = 1; A<= (P-C)/2; A++){
B = P-C-A;
if(A*A + B*B == C*C && B >= A){
number++;
}
roopCount++;
}
}
if(resultN < number){
resultP = P;
resultN = number;
}
}
System.out.println("결과 값 둘레는 " + resultP + " 이며 개수는 " + resultN);
System.out.println("Roop = " + roopCount);
}
}
2014年09月10日 13:28
풀이 작성