100 cases of C programming (9): physiological cycle

Time:2020-6-4

Physiological cycle

Problem description

There are three physiological cycles in human life, namely, physical, emotional and intellectual cycles. Their cycle length is 23 days, 28 days and 33 days. One day in each cycle is the peak. On the peak day, people will perform well in corresponding aspects. For example, at the peak of the intelligence cycle, people are quick in thinking and easy to concentrate. Because the perimeter of three cycles is different, the peak of three cycles usually does not fall on the same day. For everyone, we want to know when the three peaks fall on the same day.

For each cycle, we will give the number of days from the first day of the current year to the peak (not necessarily the first peak). Your task is to give a number of days from the first day of the year, and output the time (days from the given time) when the next three peaks fall on the same day from the given time (excluding the given time). For example, if the given time is 10 and the next three peaks occur on the same day is 12, then output 2 (note that this is not 3).

input data

Enter four integers: P, e, I, and D. p. E, I represent the time when the peak of physical strength, emotion and intelligence occurs (calculated from the first day of the year). D is the given time, which may be less than P, e, or I. All given times are nonnegative and less than 365, and the time required is less than or equal to 21252.

Output requirements

The time (days away from the given time) of the same day for the next three peaks from the given time.

sample input

0 0 0 0

0 0 0 100

5 20 34 325

4 5 6 7

283 102 23 320

-1 -1 -1 -1

sample output

Case 1: the next triple peak occurs in 21252 days.

Case 2: the next triple peak occurs in 21152 days.

Case 3: the next triple peak occurs in 19575 days.

Case 4: the next triple peak occurs in 16994 days.

Case 5: the next triple peak occurs in 8910 days.

(1) Programming idea 1.

Suppose that from the first day of the year, the three peaks appear at the same time on day K. K must be greater than D and less than or equal to 21252 (23 × 28 × 33), and meet the following three conditions:

1)(k-p) % 23 == 0

2)(k-e) % 28 == 0

3)(k-i) % 33 == 0

Every k in the interval [D + 121252] is judged by three conditions. If three conditions are satisfied at the same time, then K is the result.

(2) Source 1.

#include

int main()

{

    int p,e,i,d,caseNo = 0,k;

    while(scanf(“%d%d%d%d”,&p,&e,&i,&d) &&p!=-1)

    {

        ++caseNo;

        for(k = d+1;(k-p)%23!=0 || (k-e)%28!=0|| (k-i)%33!=0; k++);

        printf(“Case %d: the next triple peak occurs in %d days.\n”,caseNo,k-d);

    }

    return 0;

}

(3) Programming idea 2.

In idea 1, each K in interval [D + 121252] is judged by three conditions, which is expensive and can be optimized.

The specific optimization method is: first, find the time K1 of the first physical peak meeting condition 1) from the interval [D + 121252], and then from K1, K1 + 23, K1 + 2 * 23, K1 + 3 * 23 Among these times, look for the first time to meet the condition 2) when the emotional peak appears. Of course, it must also be the time when the physical peak appears. Finally, in K2, K2 + 23 * 28, K1 + 2 * 23 * 28, K1 + 3 * 23 * 28 Among these times, the first time k 3 satisfying condition 3) is found. K3-d is the answer.

(4) Source 2.

#include

int main()

{

    int p,e,i,d,caseNo = 0,k;

    while(scanf(“%d%d%d%d”,&p,&e,&i,&d) &&p!=-1)

    {

        ++caseNo;

For (k = D + 1; (k-p)% 23; K + +); / / enumerate physical peak

While ((k-e)% 28! = 0) K + = 23; / / enumerate emotional peaks

While ((k-i)% 33! = 0) K + = 23 * 28; / / three peaks found

        printf(“Case %d: the next triple peak occurs in %d days.\n”,caseNo,k-d);

    }

    return 0;

}

Exercise 9

9-1 coin scheme

Problem description

There are 50 coins, which may include four types: 1 yuan, 5 jiao, 1 jiao and 5 fen.

It is known that the total value of 50 coins is 20 yuan. Find the number of coins.

For example, 2, 34, 6 and 8 are one solution. While 2, 33, 15 and 0 are another possible solution, which is obviously not unique.

How many kinds of different schemes can be found out by programming?

input data

nothing

Output requirements

For all possible schemes, see the output sample for the output format.

sample input

No input

sample output

1: 0 , 38 , 8 , 4

2: 1 , 36 , 7 , 6

3: 2 , 33 , 15 , 0

……

(1) Programming ideas.

Directly enumerate the number of four types of coins. Among them, there are 20 pieces at most in RMB 1, 40 pieces at most in RMB 5, 50 pieces at most in RMB 1 and 50 pieces at most in RMB 5.

In addition, if the unit is element, then 5, 1 and 5 will be converted into floating-point data, which is prone to calculation errors. You can change 1 yuan, 5 jiao, 1 jiao and 5 points into 100 points, 50 points, 10 points and 5 points, so that all of them are processed with integer data.

(2) Source program.

#include

int main()

{

    int a,b,c,d,cnt=0;

    for(a=0;a<=20;a++)

     for(b=0;b<=40;b++)

      for(c=0;c<=50;c++)

       for(d=0;d<=50;d++)

       {

                     if(a*100+b*50+c*10+d*5==2000 && a+b+c+d==50)

                     {

                            printf(“%d: %d , %d , %d , %d\n”,++cnt,a,b,c,d);

                     }

        }

    return 0;

(3) Exhaustively optimize.

The above program is solved by exhaustive method, which is relatively simple. However, there is room for improvement and Optimization in the setting of exhaustive structure and the selection of exhaustive parameters.

Generally speaking, when the exhaustive method is used to solve the problem, two aspects can be considered for optimization.

1) Build a simple mathematical model.

The number of variables in the mathematical model should be as small as possible, and they are independent of each other. In this way, the dimension of search space is small. In response to the program code, there are fewer levels of loop nesting. For example, in the above program, variables a, B, C and D are used to represent the number of 1 yuan, 5 jiao, 1 jiao and 5 fen coins respectively. The four variables are exhaustive, and the cycle level is 4 layers. In fact, these four variables have two constraints on each other, or the number is equal to 50, or the total value is 20 yuan. Therefore, only three variables can be exhausted, and the other one can be obtained by constraints, thus reducing the cycle level to three levels.

2) Reduce search space.

Using the existing knowledge, we can narrow the value range of each variable in the mathematical model and avoid unnecessary calculation. In response to the program code, the number of times the loop body is executed is reduced. For example, when exhausting, first consider the number a of 1 yuan, up to 20 pieces (i.e. 0 < = a < = 20), then consider the number B of 5 corners. If the total value is not more than 20 yuan, then the number of pieces is up to (2000-a * 100) / 50 (i.e. 0 < = B < = (2000-a * 100) / 50). Then consider the number C of 1 corner, and the number of pieces is up to (2000-a * 100-b * 50) / 10 (i.e. 0 < = C < = (2000-a * 100-b * 50) / 10). In this way, the number of cycles of exhaustion will be greatly reduced.

The optimized source program is as follows.

#include

int main()

{

    int a,b,c,d,cnt=0;

    for(a=0;a<=20;a++)

     for(b=0;b<=(2000-a*100)/50;b++)

      for(c=0;c<=(2000-a*100-b*50)/10;c++)

        {

D = (2000-a * 100-b * 50-c * 10) / 5; / / fill the rest with 5 cents

                     if(a+b+c+d==50)

                     {

                            printf(“%d: %d , %d , %d , %d\n”,++cnt,a,b,c,d);

                     }

        }

    return 0;

}

It is also possible to use a total number of no more than 50 restraints. First, consider the number a of 1 yuan, which is 20 at most (i.e. 0 < = a < = 20), then consider the number B of 5 angles, which is 50-a at most (i.e. 0 < = B < = (50-a), then consider the number C of 1 angle, which is 50-a-b at most (i.e. 0 < = C < = 50-a-b). The optimized source program is as follows.

#include

int main()

{

    int a,b,c,d,cnt=0;

    for(a=0;a<=20;a++)

     for(b=0;b<=50-a;b++)

      for(c=0;c<=50-a-b;c++)

            {

D = 50-a-b-c; / / fill the rest with 5 cents

                     if(100*a+50*b+10*c+5*d==2000)

                     {

                            printf(“%d: %d , %d , %d , %d\n”,++cnt,a,b,c,d);

                     }

            }

    return 0;

}

9-2 summation triangle

Problem description

If the sum of the numbers on three sides of the triangle is equal and the product of the numbers on three sides is equal, the triangle is called the sum product triangle.

 

Figure 1 Digital triangle

For example, the summation triangle with a sum of 45 is shown in Figure 2.

Figure 2 summation triangle of S = 45

Write a program, output and sum triangle of S.

input data

A positive integer s (36 ≤ s ≤ 300).

Output requirements

All summation triangles whose sum is s require that the output scheme is not repeated. As shown in Figure 2, 8 and 9 are exchanged, or 4 and 3 are exchanged, or 9 and 4, 8 and 3, 2 and 12 are exchanged at the same time, the three schemes obtained are all regarded as the same scheme as those given in Figure 2.

sample input

45

sample output

1:2 , 8 , 9 , 1 , 4 , 3 , 12 , 6 ,   s1=20, s2=144

explain

Referring to the data in Figure 2, notice the output order of 8 numbers in the example. In addition, the value of S1 represents the sum of integers on each side, and the value of S2 represents the product of integers on each side.

(1) Programming ideas.

According to the description of the output sample, set the distribution of 8 numbers of the digital triangles shown in Figure 1 as shown in Figure 3 below.

Because the two waists of the triangle can be exchanged with each other, in order to avoid repetition, it is advisable to agree that the number in the triangle is “small at the bottom and large at the top, small at the left and large at the right”, that is, B1

 

Figure 3 triangle distribution

In this way, the values of B1 and B7 can be explored circularly according to the Convention, and the following settings can be set:

The value range of B1 is 1 ~ (S-21) / 2; (because the sum of other 6 numbers except B1 and B7 is at least 21)

The value range of B7 is B1 + 1 ~ (S-28); (because the sum of other 7 numbers except B7 is at least 28)

The value range of B4 is 1 ~ (S-28); (because the sum of 7 numbers except B4 is at least 28)

Similarly, according to the agreement B2

The value range of B 2 is 1 ~ (S-21) / 2; (because the sum of the other six numbers except B 2 and B 3 is at least 21)

The value range of B3 is B 2 + 1 ~ (S-28);

The value range of B6 is 1 ~ (S-21) / 2; (because the sum of other six numbers except B5 and B6 is at least 21)

The value range of B5 is B (6) + 1 ~ (S-28);

b8 = s-(b1+b2+b3+b4+b5+b6+b7)

For the 8 integers, the following 4 tests are required:

1) If B8 < = 0, it does not meet the requirements;

2) If the eight numbers are the same, the requirements are not met;

3) If the sum of the three sides is not equal, it does not meet the requirements;

4) If the product of three sides is not equal, it does not meet the requirements.

If a certain number of 8 passes the above 4-channel detection, it is a solution, printed out, and counted the number of solutions.

Because it is necessary to detect whether the same number appears in 8 integers, 8 numbers can be saved in a one-dimensional array to define one-dimensional array int b [9]; the array elements B [1] ~ B [8] respectively correspond to B1 ~ B8 in Figure 3.

The program can be written as a seven cycle structure as follows:

    for(b[1]=1;b[1]<=(s-21)/2;b[1]++)

     for(b[7]=b[1]+1;b[7]<=s-28;b[7]++)

      for(b[4]=1;b[4]<=s-28;b[4]++)

       for(b[2]=1;b[2]<=(s-21)/2;b[2]++)

        for(b[3]=b[2]+1;b[3]<=s-28;b[3]++)

         for(b[6]=1;b[6]<=(s-21)/2;b[6]++)

          for(b[5]=b[6]+1;b[5]<=s-28;b[5]++)

                     {

According to the 8 exhaustive numbers, four tests are carried out to determine whether it is a group of solutions;

                    }

In the 4-channel detection, in addition to checking whether there are the same number of complex points in the 8 numbers, the others are simply calculated and judged.

In order to detect whether the same number appears in 8 numbers, you can set a flag t = 0 first; then use the cycle to compare each number with each number after it. If the same number appears, set t = 1 and exit the cycle.

After the execution of the loop, if t = = 1, the same number appears in the 8 numbers; if t keeps the initial setting value of 0, the same number does not exist in the 8 numbers. The algorithm is described as follows:

      t=0;

     for(i=1;i<=7;i++)

             for(j=i+1;j<=8;j++)

                         if(b[i]==b[j])

                          { 

                                     t=1; i=7; break;

                           }

(2) Source 1.

#include

int main()

{

    int i,j,t,s,s1,s2,cnt,b[9];

    scanf(“%d”,&s);

    cnt=0;

    for(b[1]=1;b[1]<=(s-21)/2;b[1]++)

     for(b[7]=b[1]+1;b[7]<=s-28;b[7]++)

      for(b[4]=1;b[4]<=s-28;b[4]++)

       for(b[2]=1;b[2]<=(s-21)/2;b[2]++)

        for(b[3]=b[2]+1;b[3]<=s-28;b[3]++)

         for(b[6]=1;b[6]<=(s-21)/2;b[6]++)

          for(b[5]=b[6]+1;b[5]<=s-28;b[5]++)

            {

                              b[8]= s-(b[1]+b[2]+b[3]+b[4]+b[5]+b[6]+b[7]);

                              if(b[8]<=0)  continue;

                              t=0;

                              for(i=1;i<=7;i++)

                                 for(j=i+1;j<=8;j++)

                                        if(b[i]==b[j])

                                        {  t=1; i=7; break; }

                           if(t==1)  continue;

                           s1= b[1]+b[2]+b[3]+b[4];

                           if(b[4]+b[5]+b[6]+b[7]!=s1 || b[1]+b[8]+b[7]!=s1)

                                     continue;

                           s2=b[1]*b[2]*b[3]*b[4];

                          if(b[4]*b[5]*b[6]*b[7]!=s2 || b[1]*b[8]*b[7]!=s2)

                                     continue;

                         cnt++;

                         printf(“%d : “,cnt);

                         for(i=1; i<=8; i++)

                                 printf(“%d , “,b[i]);

                         printf(”  s1=%d, s2=%d\n”,s1,s2);

            }

    return 0;

             }

(3) We should exhaust the optimization ideas.

The above exhaustive program design is feasible. However, this program runs too slowly. For example, change s = 45 in the program to s = 89, that is, calculate the sum product triangle composed of 8 integers of 89. After the program is run, the result shown below can be obtained.

1 : 6 , 14 , 18 , 1 , 9 , 8 , 21 , 12 ,   s1=39, s2=1512

2 : 8 , 12 , 15 , 1 , 16 , 9 , 10 , 18 ,   s1=36, s2=1440

3 : 8 , 4 , 27 , 2 , 12 , 3 , 24 , 9 ,   s1=41, s2=1728

4 : 15 , 9 , 16 , 1 , 12 , 10 , 18 , 8 ,   s1=41, s2=2160

It takes a long time for the program to get the above four solutions. In order to improve the efficiency of the solution, we must optimize the program, which can start from the cycle setting. The specific ideas are as follows:

1) Whether S + B1 + B7 + B4 is a multiple of 3 was detected.

Because the elements of the three vertices of a triangle are calculated twice respectively in calculating the three sides, that is, S + B1 + B7 + B4 = 3 * S1, the detection of whether S + B1 + B7 + B4 can be divisible by 3 is added in the cycle of B1, B4 and B7.

If (s + B1 + B7 + B4)% 3 ≠ 0, then continue to explore new B1, B4 and B7 without exploring the following B2, B3, B5 and B6;

Otherwise, S1 = (s + B1 + B7 + B4) / 3 will be recorded and further exploration will be carried out.

2) Simplify the cycle and reduce the seven fold cycle to five fold.

Keep the cycle exploration on the values of B1, B7 and B4 according to the Convention, and set the same as before. Optimize the cycle exploration of B 2, B 3, b 5 and B 6. The values of B3 and B5 can be explored according to the agreement, and the following settings can be set:

The value range of B3 is (s1-b1-b4) / 2 + 1 ~ s1-b1-b4; note: S1 = (s + B1 + B7 + B4) / 3

The value range of B5 is (s1-b4-b7) / 2 + 1 ~ s1-b4-b7;

At the same time, according to the sum of each side as S1, B2, B6 and B8 are calculated, i.e

         b2=s1-b1-b4-b3

         b6=s1-b4-b5-b7

         b8=s1-b1-b7

In this way, it also simplifies the detection of whether B8 is positive or not, and the detection of whether three sides and equal. We only need to check whether B array has the same positive integer and the same trilateral product.

(4) Improved source program.

#include

int main()

{

    int i,j,t,s,s1,s2,cnt,b[9];

    scanf(“%d”,&s);

    cnt=0;

    for(b[1]=1;b[1]<=(s-21)/2;b[1]++)

     for(b[7]=b[1]+1;b[7]<=s-28;b[7]++)

      for(b[4]=1;b[4]<=s-28;b[4]++)

        {

                  if((s+b[1]+b[4]+b[7])%3!=0)

                            continue;

                  s1=(s+b[1]+b[4]+b[7])/3;

                 for(b[3]=(s1-b[1]-b[4])/2+1;b[3]

                     for(b[5]=(s1-b[4]-b[7])/2+1;b[5]

                      {

                              b[2]=s1-b[1]-b[4]-b[3];

                               b[6]=s1-b[4]-b[7]-b[5];

                              b[8]=s1-b[1]-b[7];

                              t=0;

                              for (i=1; i<=7; i++)

                                 for(j=i+1;j<=8;j++)

                                        if(b[i]==b[j])

                                       { t=1;  i=7; break; }

                             if(t==1)  continue;

                             s2=b[1]*b[2]*b[3]*b[4];

                            if(b[4]*b[5]*b[6]*b[7]!=s2 || b[1]*b[8]*b[7]!=s2)

                                   continue;

                           cnt++;

                          printf(“%d : “,cnt);

                         for(i=1; i<=8; i++)

                                 printf(“%d , “,b[i]);

                         printf(”  s1=%d, s2=%d\n”,s1,s2);

                     }

           }

    return 0;

}

When s = 89, the solution is the same as before, but the time is much shorter.

9-3 perfect expression

Problem description

Put the numbers 1, 2 9. Fill in the following 9 □ in the comprehensive operation formula including addition, subtraction, multiplication, division and power, so that the formula is valid

         □^□+□□÷□□-□□×□=0  

Number 1, 2 The 9 numbers of and 9 appear once and only once in the formula.

input data

nothing

Output requirements

Output all possible filling methods. See the output sample for the output format.

sample input

nothing

sample output

1:3 ^ 5 + 87 / 29 – 41 * 6=0

 ……

(1) Programming idea 1.

Let the six integers in the formula be a, B, x, y, Z, C from left to right, where x, y, Z are 2-bit integers, ranging from 12 to 98; a, B, C are 1-bit integers, ranging from 1 to 9.

Set a, B, C, x, y, Z cycle, and detect each group of a, B, C, x, y, Z exhaustively as follows:

1) If x is not a multiple of Y, that is, X% Y! = 0, then return to continue the next enumeration.

2) If the equation is not true, that is, a ^ B + X / Y-Z * c! = 0, then return to the next enumeration.

3) Whether 9 numbers in the formula have the same number. The 6 integers in the formula are separated into 9 numbers and assigned to the array elements f [1] ~ f [9]. Together with the additional f [0] = 0 (to ensure that 9 numbers are not 0), a total of 10 numbers are compared one by one in the double cycle.

If there is the same number, t = 1, it’s not a solution. Continue to the next enumeration.

If there is no same number, that is to say, 9 numbers in the formula are 1-9 and not repeated, keeping the mark t = 0, it is a group of solutions, and the output is the perfect formula. And count the number of solutions n.

(2) Source 1.

#include

int main()

{

    int a,b,c,x,y,z;

    int i,j,k,t,n,f[10];

    n=0;

    for(a=1;a<=9;a++)

     for(b=1;b<=9;b++)

      for(c=1;c<=9;c++)

       for(x=12;x<=98;x++)

        for(y=12;y<=98;y++)

         for(z=12;z<=98;z++)

         {

                   if (x%y!=0) continue;

                    k=1;

For (I = 1; I < = B; I + +) / / calculate k = a ^ B

                       k=a*k;

                   if(k+x/y-z*c!=0) continue;

                   f[0]=0;

F [1] = a; f [2] = B; f [3] = C; / / 9 numbers are assigned to the f array

                  f[4]=x/10; f[5]=x%10;

                  f[6]=y/10; f[7]=y%10;

                  f[8]=z/10; f[9]=z%10;

                   t=0;

                   for(i=0;i<=8;i++)

                    for(j=i+1;j<=9;j++)

                         if(f[i]==f[j])

{t = 1; break;} / / verify that the number is repeated

                    if(t==0)

                    {

N + +; / / output a solution and count the number with n

                        printf(“%d:%d ^ %d + %d / %d – %d * %d=0\n”,n,a,b,x,y,z,c);

                    }

           }

    return 0;

}

(3) Programming idea 2.

Optimize the above program.

Since the required comprehensive formula is: A ^ B + X / Y-Z * C = 0, then x = (Z * C-A ^ b) * y. Therefore, a, B, C, y, Z cycle can be set to calculate x for each set of a, B, C, y, Z that is exhausted. In this way, the X cycle can be omitted, whether x can be divisible by Y and whether the equation is valid can be omitted.

After calculating x, as long as X is detected to be two digits. If the computed x is not a binary integer, the next enumeration is returned.

In addition, this method can be used to determine whether 9 numbers in the formula have the same number:

Define f array to count the occurrence times of 9 numbers separated from 6 integers, that is, the value of F [i] is the number of numbers I in the formula, and the initial value is all assigned to 0. After statistics, I f a certain f [i] (I = 1 ~ 9) is not 1, then the numbers 1, 2 I f all f [i] are 1, the numbers 1, 2 The nine numbers of and 9 all appear once and only once, and keep the mark t = 0, which is the perfect synthesis formula of solution and output.

(4) Source 2.

#include

int main()

{

    int a,b,c,x,y,z;

    int i,k,t,n,f[10];

    n=0;

    for(a=1;a<=9;a++)

     for(b=1;b<=9;b++)

      for(c=1;c<=9;c++)

        for(y=12;y<=98;y++)

         for(z=12;z<=98;z++)

          {

                 k=1;

                for (i=1;i<=b;i++)

                        k=a*k;

                x=(z*c-k)*y;

                if(x<10 || x>98)  continue;

                for(i=1;i<=9;i++)

                        f[i]=0;

F [a] + +; f [b] +; f [C] +; / / record the number of times that 9 numbers appear respectively

                f[x/10]++;  f[x%10]++;   f[y/10]++;  f[y%10]++;

                 f[z/10]++;  f[z%10]++;

                 t=0;

               for(i=1;i<=9;i++)

                    if(f[i]!=1)

{t = 1; break;} / / verify that the number is repeated

              if(t==0)

                {

                         n++;

                        printf(“%d:%d ^ %d + %d / %d – %d * %d=0\n”,n,a,b,x,y,z,c);

                 }

           }

     return 0;

Recommended Today

The way of nonlinear optimization

Mathematical knowledge 1、 Nonlinear functionLinear function is another name of a function of first degree, then nonlinear function means that the function image is not a function of a straight line.Nonlinear functions include exponential function, power function, logarithmic function, polynomial function and so on. 2、 Taylor expansion1. Taylor formula:Taylor’s formula is to add a_ The […]