Test instructions
A lattice of n rows m columns is given to find out how many non-horizontal non-vertical lines pass at least two points.
Analysis:
First of all, the purple book on the idea, programming is simple and easy to understand. Because of symmetry, so only the "\" This type of line, the last multiply 2 is the answer.
Enumerating the size of a slash bounding box, if the box's long-width ab coprime, is possible. This box has a total of (m-a) (n-b), but subtract the duplicates. If there is a large box with a width of 2a and 2b, then the small box in the lower right corner is counted while the small box in the upper-left corner repeats, so subtract the number of duplicate boxes C = Max (0, M-2A) * MAX (0, N-2B)
The value of the last gcd (A, b) is to be preprocessed
1#include <cstdio>2#include <algorithm>3 4 Const intMAXN = -;5 intgcd[maxn+Ten][maxn+Ten];6 7 intGCD (intAintb)8 {9 returnb = =0? A:GCD (b, a%b);Ten } One A intMain () - { - for(inti =1; I <= MAXN; ++i) the for(intj =1; J <= I; ++j) -GCD[I][J] = Gcd[j][i] =GCD (i, j); - - intN, M; + while(SCANF ("%d%d", &n, &m) = =2&&N) - { + intAns =0; A for(intA =1; a <= N; ++a) at for(intb =1; b <= m; ++b) - if(Gcd[a][b] = =1) - { - intc = Std::max (0, n-a*2) * Std::max (0, m-b*2); -Ans + = (n-a) * (m-b)-C; - } in -printf"%d\n", ans *2); to } + - return 0; the}
code June
Solution Two:
The solution is transferred from UVA 1393-highways (counting the principle of tolerance)
DP (i, j) indicates how many non-repeating lines can be connected from the upper left corner in a box with a length of IJ.
can be recursive DP (i, j) = DP (I-1, J) + DP (i, J-1)-DP (I-1, J-1) + (GCD (i, j) = 1) (Because the box has a long coprime on both sides to make a new edge)
The final answer is the same in the form of ans recursion, but the repeated lines are those that still exist after shrinking twice times.
Ans (i, j) = ans (i-1, J) + ans (i, j-1)-ans (i-1, j-1) + DP (i, j)-DP (I/2, J/2)
In the final code, Ben thought that only half of the answers would be faster, with the results ranked 21 and the list failed.
1#include <cstdio>2#include <algorithm>3 4 Const intMAXN = -;5 intdp[maxn+1][maxn+1], ans[maxn+1][maxn+1];6 7 intgcdintAintb)8 {9 returnb = =0? A:GCD (b, a%b);Ten } One A voidInit () - { - for(inti =1; I <= MAXN; ++i) the for(intj =1; J <= I; ++j) - { - if(i = = j) Dp[i][j] = dp[i][j-1] *2-dp[i-1][j-1] + (GCD (i, j) = =1); - ElseDP[I][J] = dp[i-1][J] + dp[i][j-1]-dp[i-1][j-1] + (GCD (i, j) = =1); + } - + for(inti =1; I <= MAXN; ++i) A for(intj =1; J <= I; ++j) at { - if(i = = j) Ans[i][j] = ans[i][j-1] *2-ans[i-1][j-1] + dp[i][j]-dp[i/2][j/2]; - ElseANS[I][J] = ans[i][j-1] + ans[i-1][J]-ans[i-1][j-1] + dp[i][j]-dp[i/2][j/2]; - } - } - in intMain () - { to Init (); + intN, M; - while(SCANF ("%d%d", &n, &m) = =2&&N) the { * if(N <m) std::swap (n, m); $printf"%d\n", ans[n-1][m-1]*2);Panax Notoginseng } - the return 0; +}
code June
UVa 1393 (tolerant principle, GCD) highways