본문 바로가기
반응형

프로젝트 오일러69

49. 프로젝트 오일러 #49 : 소수 순열 이 문제는 좀 복잡해보이기는 하지만, 실제 풀이과정은 단순한 문제입니다. 세개의 4자리 숫자는 숫자들의 순서만 다르면서 소수인 숫자들입니다. 예를 들어서 1487, 4817, 8147 세 숫자는 1, 4, 7, 8 의 4개의 숫자들을 순서만 달리하면서, 각각이 소수인 숫자들입니다. 이러한 조건을 만족하는 또다른 숫자 조합을 찾으라는 것이 이 문제입니다. (실제 모든 경우를 해도, 4자리 숫자는 예를 든 것과 여기서 원하는 답, 이렇게 두가지밖에 없습니다.) 다음 그림은 프로젝트 오일러 사이트에 있는 문제입니다. 알고리즘을 작성할 때, 4자리로 만드는 순열을 어떻게 만들것인가가 가장 중요했습니다. 모든 경우를 다 찾아봐도 되겠지만, 그러면 경우의 수가 너무 많아집니다. 그래서 제 경우에는 4개의 숫자를 고.. 2016. 6. 3.
48. 프로젝트 오일러 #48 : 자체 제곱수 이번 48번 문제도 쉬운 문제입니다. 내용도 상당히 짧습니다. 난이도는 5%입니다. 이 문제에서 핵심이 되는 내용은 바로 결과물의 아래 열자리만 구하라는 것입니다. 그렇지 않다면, 사실 일반 프로그래밍 언어의 정수형 변수로는 계산할 수가 없습니다. 1000의 1000승이면, 0이 3000개나 되고요. 이진수로 표현하려면 10,000비트(1,250바이트)정도가 필요합니다. 자체 제곱을 하는데 있어서 좀 더 유연하게 할 수는 있습니다. 예를 들어서 2의 8승을 구하기 위해서는 2의 4승을 구해서 제곱을 하면 되겠죠. 이런 식으로 지수의 곱을 줄여줄 수 있지만, 그런 고급 기법은 암호화 알고리즘에서나 쓰면 됩니다. 암호화 알고리즘에서는 수억, 수천억제곱보다 더 한 것들을 합니다. 512비트를 쓴다면, 10의 .. 2016. 6. 2.
47. 프로젝트 오일러 #47 : 서로 다른 소인수 프로젝트 오일러 #47 문제는 소인수 분해를 하기만 하면, 어렵지 않게 풀 수 있습니다. 난이도는 5%입니다. 문제는 4개의 연달은 숫자들의 각각의 소인수 갯수가 4개인 첫번째 숫자를 찾으라는 것입니다. 그동안 소인수분해는 많이 해왔지만, 이와 같은 문제는 미리 소수를 찾아내는 것이 편합니다. 범위가 지정되어 있지 않으므로, 충분히 큰 수까지 찾을 수도 있지만, 문제를 풀면서, 소인수분해한 결과가 소수이면, 소수 리스트에 저장하는 방법도 있을 수 있습니다. 제 경우에는 소수 리스트를 관리하지 않고, 작은 수부터 인수를 찾는 방식으로 했습니다. #include bool GetPFactor(int p, int r); int main() { int count = 0; for( int i = 644 ; ; i+.. 2016. 6. 1.
46. 프로젝트 오일러 #46 : 골드바흐의 다른 추측 이번문제는 골드바흐의 소수에 관련된 오래된 추측과 모양만 유사한 문제입니다. 골드바흐의 추측은 당시 많은 수학자들의 예상을 깨고, 아직까지 증명되지 않은 문제입니다. (홀수 완전수와 비슷하게 증명이 쉽게 이루어질거라는 예상을 깨고서 아직까지 증명되지 않았습니다.) 문제의 난이도는 5%로 상당히 낮습니다. 풀이 자체가 어렵지 않습니다. 문제를 살펴보면 다음과 같습니다. 영어를 해석하는 데 문제가 없다면, 이 문제를 푸는 데 어려움도 없을겁니다. 모든 홀수 합성수(1과 소수를 제외한 자연수)는 소수와 제곱수의 2배수의 합으로 표현이 된다는 추측입니다. 하지만 이 추측은 거짓으로 증명됩니다. 거짓이 되는 가장 작은 홀수 합성수는 얼마일까요? 이 문제는 그냥 단순하게 적용하면 별 무리 없이 풀 수 있습니다. 저.. 2016. 5. 31.
프로젝트 오일러 #45 삼각수, 오각수, 육각수 삼각수, 오각수, 육각수라는 것은 앞에 #44(http://sdev.tistory.com/224)에서 설명한 것과 같이 도형을 그릴 때, 발생하는 점들의 갯수입니다. 이 문제에서 원하는 것은 40755 다음에 나타나는, 삼각수이자, 오각수, 그리고 육각수인 숫자를 찾는 것입니다. 삼각수를 기준으로 하든지, 육각수를 기준으로 하든지, 다른 숫자들을 맞추어 나가면 됩니다. 간단하게 공차식을 구해서 계산하는 것이 편하겠죠. 그래서 만들어진 소스는 다음과 같습니다. #include #include int main() { uint64_t t = 40755, p = 40755, h = 40755; uint64_t dt = 286, dp = 496, dh = 573; t += dt; dt++; while( 1 ) {.. 2016. 5. 27.
43. 프로젝트 오일러 #43 : 부분 문자열 나누어 떨어지기 이번 문제도 간단한 문제입니다. (난이도 5%) 문제 자체는 팬디지털(0~9까지의 숫자를 한번씩만 쓴 숫자)의 부분 문자열이 특정 소수로 나누어지는 가를 판별하면 됩니다. 가장 손쉽게 구현할 수 있는 방법은 백트랙킹(back tracking) 방법을 사용합니다. 속도를 조금이라도 빠르게 하기 위해서 숫자를 만들 때, 세개의 숫자를 쓰는 것이 아니라, 기존의 값에 10을 곱한 후 새로운 값을 더하는 방식으로 구현했습니다. (사실 그다지 이것에 의해서 속도 차이가 발생하지는 않을겁니다.) 간단한 형태의 자기호출 함수를 사용해서 만들었습니다. 소스에 대한 설명은 굳이 필요하지는 않을 듯 하네요. #include #include uint64_t SumPD(uint64_t n, int mask, int t); i.. 2016. 5. 25.
728x90