Use and optimization of the for loop: solving integer indefinite equations

qualitative analysis

How do I get an integer solution to this equation? Reference Video

Equation:

Functions f1, f2, and f3:

The derivative of F1 and f2, the slope of curve f, is theoretically steeper than that of f1, where F1 and F2 have only a limited number of intersections.

The integer solution of the equation is the intersection of the curve F1 and f2.Due to the inconvenience of F1 drawing, it can be inferred from the morphology of F2 and f3 that F1 and F2 have only limited intersections.Because f3 is only a translation of f1.The images of F2 and f3 are illustrated below, with apparently only a limited number of intersections.

ps: x is symmetric, so if there is an integer solution of x, -x is also the solution.The following discussion is based on positive x integers.

Great miracle

thinking

Regardless of 3721, x and y start with 0 and try in an increasing way of natural numbers.

There are two loops, the outer is x and the inner is y.Then try to calculate f1 and f2, and if f1 == f2 print the result, terminating the cycle.

But here's a little local optimization: x^2+615=2^y >=615 can launch y>9.The outer loop x starts from 0, and the memory loop can start from 10.

Code

equation.cpp

`#include <iostream> #include <cmath> using namespace std; int main(int argc, char* argv[]) {if (argc < 3) return-1; > long n = atol(argv[1]); long M = atol(argv[2]); bool flag = false; //find the flag for the solution, find the flag for which true was not found as false (long x = 0; x < n && flag;Continue {for (long y = 10; y < m; y ++) {long F1 = 615 + pow(x, 2); {long F2 = pow(2, y);If (f1 == f2) // find, print solutions, and print keywords < < (< -x < < < < (x, y)) <<< < < < < < < (x, y)) "<<< << < << < < < < < < < < < < < < < < < < < < < < < < < < < <'))) < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < The resu lt is that//Conjugate Solution * break; *} * return} 0;} copy code`

Code Interpretation

n and m are command inputs that control the upper bounds of x and y.

flag is the symbol of finding the solution.

The exterior loop terminates when the value of the expression x < n && flag is false.

This solution is very natural and basically within the scope of great miracles.

local optimization

thinking

• Reduce the number of outer loops.

• Refer to the video and infer that x is 6k+1 or 6k-1 and K is an integer

Code

`#include <iostream> #include <cmath> using namespace std; int main(int argc, char* argv[]) {if (argc < 3) return-1; * long n = atol(argv[1]); long M = atol(argv[2]); bool flag = false; for (long k = 1; K < n && flag; k+) {for (long y = 10; y < m);Long F1 = 615 + pow(6*k - 1,2); * long F2 = pow(2,y); * if (f1 == f2); * if (flag = true); cout < <'(x, y)'<':' < (< < 6*k - 1 <',"<< y <") "<< endl; << cout <<" (x, y) "<<": "<<" ("< -(6*k-1) <<", "<< y <") "<< endl; << endl; << break; <} F2 = 615 + pow(6*k + 1, 2);(iii) if if (f1 === f2)) if (f1 === f2) tabtabtab {{Flag = false; (iix) tab tabtabtab) cout <<< < "(x, y)" <<< < < "<<< < < < < 6*k + 1 <<<<< << << < < < < < < < < < < < < < < < < < < < < < < < < < < < - - - (*k *k + 1) < < < < < < < < < < < << endl;Return 0;} Copy the code`

Code Interpretation

n and m are command inputs that control the upper bounds of x and y.

flag is the symbol of finding the solution.

The exterior loop terminates when the value of the expression K < n && flag is false.

This solution is the same as making miracle ideas vigorously. It just makes a simple inference and determines the form of x. Compared with method one, it can have 67% fewer cycles.

global optimization

thinking

• Remove a layer of looping.We can first calculate the result of 2^y and derive the value of X from the equation: x = sqrt(2^y - 615).After x is rounded, whether [x]^2 + 615 is equal to 2^y is calculated based on the result of rounding.Here [x] means rounding X.

• Remove the pow call and use sqrt only once.When calculating 2^y, you can multiply 2 by the number of outer loops.

• y must be greater than 9, so you don't have to do unnecessary calculations, so start with 10.

Code

` #include <iostream> #include <cmath> using namespace std; int main(int argc, char* argv[]) {     if (argc < 2) return -1;     long n = atol(argv[1]);     long long p = 512; //2^9 == 512) for (long y = 10; y < n; y++) {long x = sqrt(p - 615); / if (x *x + 615 == p) / /determine that x is really an integer and satisfies the equation; {cout < < < (< < < <', < < <')< < < '< <') endl;Cout <<'(x, y) ='<' () < < -x <', < < y <') < < < '<' <')'< < endl; <} * break; *} return 0;} # # code interpretation P stores 2^y values, pushes back x values, calculates x^2 + 615 after rounding, whether equal to 2^y.This method doesn't need flag either, because a direct break terminates with only one loop.Execution Resu lt s Copy Code`

Code Interpretation

Reduce the loop by only one sqrt call within the loop.In theory, it should be more efficient than methods one and two.

summary

Of the three methods, the third is obviously the better one.

How to improve efficiency in this case:

• Local optimization, such as mathematical optimization first

• Global optimization, not only from the mathematical point of view, but also from the reverse thinking, starting from y to export x, and then from X to check y.

• Avoid full circulation

• Use function calls as little as possible in a loop, and use simple addition and multiplication more often.

Biguo College

Tencent Classroom Biguo College is a platform dedicated to C/C++/Python stack-wide learning.Biguo College offers one-stop teaching from MFC/QT clients to linux servers, embedded to the Internet of Things, game development to game cracking.Suitable for 0-based junior high school students with interest in programming, college students with programmer-oriented career and junior middle programmers who don't need to be promoted urgently.

• C/C++ QT/UI