Quantcast
Channel: YGC » c++
Viewing all articles
Browse latest Browse all 18

project euler -- problem 64

$
0
0

All square roots are periodic when written as continued fractions and can be written in the form:
\( \sqrt{N}= a0 + \frac{1}{a1+\frac{1}{a2+\frac{1}{a3+...}}}\)
For example, let us consider √23
\( \sqrt{23}= 4 +\sqrt{23} -4 = 4 + \frac{1}{\frac{1}{\frac{1}{\sqrt{23}-4}}} = 4+\frac{1}{1+\frac{\sqrt{23}-3}{7}}\)
If we continue we would get the following expansion:
\( \sqrt{23}= 4 + \frac{1}{1+\frac{1}{3+\frac{1}{1+\frac{1}{8+...}}}}\)

The process can be summarised as follows:
\( a0=4,\frac{1}{\sqrt{23}-4}=\frac{\sqrt{23}+4}{7}=1+\frac{\sqrt{23}-3}{7}\)
\( a1=1,\frac{7}{\sqrt{23}-3}=\frac{7(\sqrt{23}+3)}{14}=3+\frac{\sqrt{23}-3}{2}\)
\( a2=3,\frac{2}{\sqrt{23}-3}=\frac{2(\sqrt{23}+3)}{14}=1+\frac{\sqrt{23}-4}{7}\)
\( a3=1,\frac{7}{\sqrt{23}-4}=\frac{7(\sqrt{23}+4)}{7}=8+\sqrt{23}-4\)
\( a4=8,\frac{1}{\sqrt{23}-4}=\frac{\sqrt{23}+4}{7}=1+\frac{\sqrt{23}-3}{7}\)
\( a5=1,\frac{7}{\sqrt{23}-3}=\frac{2(\sqrt{23}+3)}{14}=3+\frac{\sqrt{23}-3}{2}\)
\( a6=3,\frac{2}{\sqrt{23}-3}=\frac{2(\sqrt{23}+3)}{14}=1+\frac{\sqrt{23}-4}{7}\)
\( a7=1,\frac{7}{\sqrt{23}-4}=\frac{7(\sqrt{23}+4)}{7}=8+\sqrt{23}-4\)
It can be seen that the sequence is repeating. For conciseness, we use the notation √23 = [4;(1,3,1,8)], to indicate that the block (1,3,1,8) repeats indefinitely.
The first ten continued fraction representations of (irrational) square roots are:
√3=[1;(1,2)], period=2
√5=[2;(4)], period=1
√6=[2;(2,4)], period=2
√7=[2;(1,1,1,4)], period=4
√8=[2;(1,4)], period=2
√10=[3;(6)], period=1
√11=[3;(3,6)], period=2
√12= [3;(2,6)], period=2
√13=[3;(1,1,1,1,6)], period=5

Exactly four continued fractions, for N ≤ 13, have an odd period.
How many continued fractions for N ≤ 10000 have an odd period?

把无理数拆解成连分数,连分数只有在小学的时候碰到过,那时候做的是这题的逆运算,求解连分数,利用到的信息就是continued fractions重复出现的特点,把题变成求解方程。对于这道题,我的思路正是源自于小学解方程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <iostream>
#include <cmath>
#include <vector>
 
using namespace std;
 
class FRAC {
private:
  int sq;
  int nom;
  int den;
public:
  FRAC(int s, int n=0, int d=1);
  int get_a() const;
  FRAC expand() const;
  friend bool operator==(const FRAC f1, const FRAC f2);
};
 
bool is_rational(int n);
int get_continued_fraction_count(int n);
 
int main() {
  int odd_cnt = 0;
  for (int i = 2; i <= 10000; i++) {
    if (is_rational(i))
      continue;
    int cnt = get_continued_fraction_count(i);
    if (cnt % 2 == 1)
      odd_cnt += 1;
  }
  cout << odd_cnt << endl;
  return 0;
}
 
bool operator==(const FRAC f1, const FRAC f2) {
  if ( (f1.sq == f2.sq) &&
       (f1.nom == f2.nom) &&
       (f1.den == f2.den) )
    return true;
  return false;
}
 
FRAC::FRAC(int s, int n, int d) {
  sq = s;
  nom = n;
  den = d;
}
 
int FRAC::get_a() const {
  int a = ((int) sqrt(sq) + nom)/den;
  return a;
}
 
FRAC FRAC::expand() const {
  int a = this->get_a();
  int n = a * den -nom;
  int d = (sq - n*n)/den;
  FRAC a1 = FRAC(sq, n, d);
  return a1;
}
 
int get_continued_fraction_count(int n) {
  FRAC f = FRAC(n);
 
  vector<FRAC> fv;
  vector<int> av;
  int a = f.get_a();
  av.push_back(a);
  FRAC nf = f.expand();
  fv.push_back(nf);
 
  int begin;
  while(true) {
    bool flag = false;
    FRAC new_frac = nf.expand();
    int a = nf.get_a();
    for (int i = 0; i < fv.size(); i++) {
      if (new_frac == fv[i]) {
	begin = i+1;
	flag = true;
	break;
      }
    }
 
    fv.push_back(new_frac);
    av.push_back(a);
    if (flag)
      break;
    nf = new_frac;
  }
  int res = av.size() - begin;
  return res;
}
 
bool is_rational(int n) {
  double x = sqrt(n);
  if (floor(x) * floor(x) == n)
    return true;
  return false;
}

Related Posts


Viewing all articles
Browse latest Browse all 18

Trending Articles