A square of the number n of radius r can put up to the round?

Today saw the number of homes the group was discussing an interesting topic, so I also used to do a bit curious. Meaning of the questions seems to be this: How many can hold up to a radius of a circle as a 10x10 square's? Big brother have found a square 10 * 10 can be placed in a number of known diameter in almost a circle, then the best place as follows:
Here Insert Picture Description
As can be seen from the figure, not every discharge 10, the discharge 10 rows It is optimal. Because this will cause great middle of the gap. It may be seen more optimal method is to place: staggered release, i.e. (from the bottom up in FIGS.): First drain 10, second drain 9, the third discharge 10. Each of the second row are placed in the middle of the two, although this second row put a little, but it gives a smaller footprint height. If you have been so put out it is likely to make a total height put a row. But we do not know in exchange for a reduction in the number of highly than stay whether it is worth it. (Such as shown below: 3 is the side length of the square, then placed staggered, only put 3 + 3 + 2 = 8, so that less red than the height insufficient to recapture left to the next row)
Here Insert Picture Description
To simplify matters, only discuss side length of the square where the diameter of the circle be divisible.
How should decisions it? Now determine the best method is to put each row are either filled with the n, and a row of staggered or put, put the n-1 or n number, because it can take up minimal height.
If you do not put staggered, so it takes up height it is 2r. If the staggered release, with the Pythagorean theorem to calculate height is occupied by √3r. As shown in the following figure:
Here Insert Picture Descriptionit is easy to think of using dynamic programming to solve this problem. Because of its decision-making stage obviously it has been divided into rows and rows, and each row there are two kinds of decision making. Because it also records the height of the decision-making process. So, to use a one-dimensional to facilitate the calculation of the current placement height. You can add a status to indicate how many times the staggered placement. Such a state is defined: with denoted f [i] [j] [ k]: When the front row i, a j-th interleaved, and placed in the state i-th row is k, the maximum number is placed round. Wherein only two values ​​k, k = 0 indicates that the discharge time represents s-1 (where s = n / 2r) When the full discharge of s, k = 1. Whether the judgment is a mistake to put only need to determine k k and the line on the line are not equal. At the same time it is also necessary to calculate its current height, the height can be recorded with g [i] [j] [k].

This is so that their state transition equation is easy to write:
remember just to put every full discharge of s.

f[i][j][0]=max(f[i-1][j-1][1],f[i-1][j][0])+s
g[i][j][0]=g[i-1][j-1][1]+√3r , 当f[i-1][j-1][0]<f[i-1][j][1]时
g[i][j][0]=g[i-1][j][0]+2r , 当f[i-1][j-1][0]>f[i-1][j][1]时

He explained: f [i] [j] [0]: i front row j-th interleaving put, and the i-th emission is full, the number of put up. It can also be put over a row of filled transfer time, since both the row and a row s put a, a mistake so the same number of times, the state of a row k is 0, that is: f [i-1 ] [j] [0]. May not put on one line by the full state, then the increase in the number of interleave 1, the state of a row k is 1, a f [i-1] [j-1] [1] transfer over. After taking both plus a maximum number of the row is placed on a f [i] [j] [0] values. Calculating the height based on whether g k is the same before and after the transfer (k equal to 2R increase, or increase √3r).

Similarly there are:
F [I] [J] [. 1] = F [. 1-I] [J-. 1] [0] +. 1 S-
G [I] [J] [. 1] = G [. 1-I] [j-1] [0] + √3 * r

Explanation: The transfer of only one state here, because the current i-emissions is s-1 Ge, if a row or put the s-1 Ge, certainly not optimal, because it not only takes high 2r, which also row put a little, how also does not pay. Therefore, it goes from f [i-1] [j] [1] transfer over.

The final answer is all g [i] [j] [ k] <= n of the state max (f [i] [j ] [k])

The method can be placed with the answer back backwards, such as a square 10 * 10, the diameter of the circle is 1, 106 is the final answer. The answer f [11] [8] [ 0] which then can be drawn a total of 11 rows of discharge, which is interleaved eight times. Put the recovery method is very simple, in the first nine rows of staggered release (a total of eight staggered).
That is: The first 10 discharge, the second discharge 9, the third discharge 10, a fourth discharge 9 ..., the ninth discharge 10, after 10-11 row 10 are placed.

Using c ++ to write out the code as follows:

#include<iostream>
#include<cstdio>
#include<math.h>
using namespace std;
const int N=500;
int f[N][N][2];
double g[N][N][2];
int main()
{
    while(true)
    {
        int n,d;
        cout<<"请输入正方形的边长:";
        cin>>n;
        cout<<"请输入圆的直径: ";
        cin>>d;
        cout<<endl;
        int nn=n;
        int D=d;
        if(d%2!=0)
            n*=2,d*=2;
        double r=d/2;
        int s=n/d;
        int ans=0;
        double sqrt3=sqrt(3);

        //cout<<n<<" "<<d<<" "<<sqrt3<<" "<<s<<endl;
        int ii,jj;
        for(int i=1; i<=n; i++)
        {
            for(int j=0; j<=i; j++)
            {

                if(j>0&&f[i-1][j-1][1]>f[i-1][j][0])
                {
                    f[i][j][0]=f[i-1][j-1][1]+s;
                    g[i][j][0]=g[i-1][j-1][1]+sqrt3*r;
                }
                else
                {
                    f[i][j][0]=f[i-1][j][0]+s;
                    g[i][j][0]=g[i-1][j][0]+2*r;
                }
                if(j>0)
                {

                    f[i][j][1]=f[i-1][j-1][0]+s-1;
                    g[i][j][1]=g[i-1][j-1][0]+sqrt3*r;
                }
                if(g[i][j][0]<=n)
                    if(ans<f[i][j][0])
                        ans=f[i][j][0],ii=i,jj=j;
                if(g[i][j][1]<=n)
                    if(ans<f[i][j][1])ans=f[i][j][1],ii=i,jj=j;
            }
        }

        printf("边长为%d的正方形圆的直径为%d,可以放下:  %d   个\n",nn,D,ans);
        printf("共放置 %d 排,其中交错放置 %d 次\n\n",ii,jj);
    }

}

After the test results are as follows:
Here Insert Picture Description
In summary, I think the square 10 * 10 up down the number of the circle of radius 1 is 25.

Published 11 original articles · won praise 14 · views 1009

Guess you like

Origin blog.csdn.net/qq_41832757/article/details/102961620