The task itself: http://www.codeabbey.com/index/task_view/fibonacci-sequence--ru , my code:

#include <iostream> #include <vector> using namespace std; int main() { vector<long double> fib{0, 1}; for(int i = 1; i < 1000; i++) // По условию все числа из первой тысячи // значений последовательности { fib.push_back(fib[i] + fib[i-1]); } int N; // Первая строчка должна содержать количество проводимых тестов cin >> N; long double value[N]; for(int i = 0; i < N; i++) { cin >> value[i]; } int begin, end; for (int i = 0; i < N; i++) { if(value[i] > fib[fib.size() / 2]) // Если value находится во второй половине последовательности { begin = fib.size() / 2; while(value[i] > fib[begin]) { begin /= 2; } begin *= 2; // Возвращаюсь на шаг назад // ибо после выполнения цикла // value выходит из диапозона end = fib.size(); for( ; begin < end; begin++) { if(fib[begin] == value[i]) {cout << begin << " "; break;} } } else { end = fib.size() / 2; while (value[i] < fib[end]) { end /= 2; } end *= 2; // То же самое что и в первой ветви begin = 0; for ( ; begin < end; begin++) { if(fib[begin] == value[i]) {cout << begin << " "; break;} } } } return 0; } 

One could not make such a game and just write

 for(int i = 0; i < N; i++) for(int j = 0; j < fib.size(); j++) if(value[i] == fib[j]) cout << j + 1 << " "; 

But while reading one smart book, it became interesting for me to recreate a simplified version of the binary_search () algorithm and in general, that's it :)

On the site with the task also kindly offer data entry to check the program, I was given this:

For the sake of a small test, I tried to enter only a few of them, and more specifically, the very first, second, and fourth. To my surprise, all I got on the way out was nothing.

Disappointed in my code, I redid the code before

  vector <long double> fib {0, 1}; 
     long double value;
          cin >> value;

     int i = 1;
     int number_of_element = 1;
     while (value> fib.back ()) {
         fib.push_back (fib [i] + fib [i-1]);
         i ++;
         number_of_element ++;
     }
     cout << fixed << "Element:" << fib [i-1] << "It's number:" << --number_of_element;

to find out what I'm wrong about and at the same time check, mb just numbers come across more than the first thousand. I entered the same thing in turn: the first, second and third numbers from Test data. In all three results, the number obtained by the prog was almost identical to that entered, up to about 19 characters (I miscalculated many times on this, this is not accurate), the element number also did not exceed a thousand. Based on this, I concluded that the car just had an error after a certain number of characters. Is there any way to fix this problem?

  • one
    not. The fractional number of long double stores approximately 20 exact characters (well, 21-22). No more will you get. But you can use long arithmetic. However, the right solution is to use the modulo calculation (compare with ru.stackoverflow.com/questions/614950/… ) - pavel
  • @pavel, Unfortunately, I am not strong with number theory, could you describe in a little more detail what does modulo calculation mean in this case? Ie I need to write in the vector fib not the number itself, but taken according to some module? And take, respectively, the same number taken on the same module? - niki4iko

2 answers 2

In general, a link to a similar task. For each test, output in a separate line the minimum angle between the arrows in degrees in the format given in the example (I even took half of the code from there).

The code is written on the knee, it can (and should) be made more accurate, but I think the idea can be understood.

And the idea is very simple - we just do an operation modulo a prime number (more than one is possible, more than one, it is possible and not simple). And we believe that if it coincided in module, it will coincide without a module.

Why it is correct, you can just check that there are no identical elements in the array of fibonacci numbers within the first thousand.

 char z[40000]; long long mod(long long mm){ long long r = 0; for (int i=0; z[i]; i++){ r %= mm; r*=10; r+= z[i] - '0'; } return r%=mm; } int main () { vector< long long > xx; xx.push_back(0); xx.push_back(1); for (int i=0;i<=1000;i++) xx.push_back( (xx[xx.size() -1] + xx[xx.size() -2]) % 1000000000039LL ); int N; cin >> N; for (int i=0;i<N;i++){ cin >> z; long long R = mod(1000000000039LL); for (int I = 0; I <= 1000; I++) if (R == xx[I]){ cout << I<<" "; break; } } } 

You can make it even easier, but then there will be a problem if the input is not the number of fibonacci. It is to use the formula Binet and stupidly rumble to the main part. Accuracy is low, but it's 2 times hard to make a mistake. Well, the first 10 numbers to check hands. The advantage of this method is that you can not even read the entire line, it is important to know only the first 2 digits (and maybe even 1) and the number of digits.


In general, this site is only suitable for very beginners, even the most complex tasks are solved without any problems.

  • And by the way, let's imagine that the number entered is incorrect - well, there, they made a mistake by one in the 115th sign ... What then will your program give out? This is not hitting, just trying to figure out whether she is able to find out that the entered number is not a Fibonacci number? - Harry
  • @Harry single error will accurately verify. To increase the accuracy you need to use an additional 2 number (as in the problem). The probability of accidental incorrect recognition of the order of 0.1% in this version and 10 ^ -11 with 2 numbers. Of course, you can always pick up an example, but in the case of 5-6 numbers, this is already a very nontrivial task. - pavel
  • I mean, then the residuals will not coincide with the correct ones, so that the number will not be found, or, which is worse - the one found is wrong? - Harry
  • @Harry well, that meant, the number would not be found) formally - this is not the Fibonacci number. I wrote about percentages that a number is not recognized as a number. - pavel
  • These percentages will work on the <N limit. If you do not put it - it is interesting, for any residue there is a corresponding number? :) - Harry

I propose a simpler method :) Since there are two units, we have the problem of ambiguity. So I work for numbers, starting with the second one, setting the unit as the second Fibonacci number ...

Here is the code that gives the number of a number, but does not check whether the number is correctly entered ... So it will give the answer and NOT for the Fibonacci number. Let's hope that those are not given to the input - they did not ask us to recognize if this number is correct, right?

 int main(int argc, const char * argv[]) { string s; while(getline(cin,s,'\n')) { int ex = s.length()-1; s.insert(1,"."); double x = stod(s); int n = (log10(5.0)/2.0+log10(x)+ex)/log10((1.0+sqrt(5.0))/2)+0.5; cout << n << endl; } } 

Checked for numbers from the second to the 1001st (209-digit) :), the answers are correct ...

Rationale:

enter image description here

From where

enter image description here

If you count

enter image description here

that

enter image description here

Further we calculate by the formula :)

  • and you can also neglect the first 2 terms in the numerator and make the entire denominator constant. After that, the formula will be quite readable. - pavel
  • @pavel possible. But then it will not be so obvious what formula we used. In this case, it seemed to me that clarity should prevail over speed. - Harry
  • and it is not obvious even now, in the Binet formula 2 terms, not 1) - pavel
  • @pavel Even for the first (well, second :) numbers, the second term can be neglected ... - Harry
  • A little hard to understand your code. As I understand it, we represent the incoming number as string, using s.insert (1, ".") We insert the character "." Into s [1]. and then put the result in double x. Next comes a formula that I don’t understand and the conclusion of its value. PS There are generally questions that you have not answered?)) - niki4iko