上午小测1「木板」
上午小测1「木板」
题目大意
分析
简单推论
老数学题了,直接开搞:
\[设 \;BE = x,CE = n - x, CF = y, \angle AEF = 90^{\circ}
\]
\[\because \Delta ABE \sim \Delta ECF
\]
\[\therefore \frac{AB}{BE} = \frac{EC}{CF}
\]
\[\therefore \frac{n}{x} = \frac{n - x}{y}
\]
\[\therefore y = \frac {nx-x^2}{n} = x - \frac{x^2}{n}
\]
\[\because x\in \mathbb{Z}\;且\;y\in \mathbb{Z}
\]
\[\therefore n|x^2
\]
\[设\;n=p_1^{a_1}\times p_2^{a_2}\times p_3^{a_3}\times \cdots p_i^{a_i}(p_i\in \mathbb{P})
\]
\[\therefore x_{min} = p_1^{\left \lceil \frac{a_1}{2} \right \rceil}\times p_2^{\left \lceil \frac{a_2}{2} \right \rceil}\times p_3^{\left \lceil \frac{a_3}{2} \right \rceil}\times \cdots \times p_i^{\left \lceil \frac{a_i}{2} \right \rceil}(p_i\in \mathbb{P})
\]
\[设\; k\in \mathbb{Z}
\]
\[\because kx_{min} < n
\]
\[\therefore k < \frac{n}{x_{min}}
\]
\[易得\; ans = k - 1
\]
进一步计算
- 如何求 \(x_{min}\) ?
会发现,每个质因子次幂是向上取整的,当次幂是奇数的时候,有一个 \(p_i\) 是必须选取的,剩下的选一半即可。
\[设\; n=2^3\times 3^2\times 5^1
\]
\[x_{min} = 2^2\times 3^1\times 5^1
\]
\[有\; 2^1\; 和\; 5^1\; 是必选的
\]
\[设\; i (i ^ 2\leq n\; 且\; i^2|n), b = 2^1\times 5^1
\]
\[\because i_{max} = 2^1\times 3^1
\]
\[\therefore b = \frac{n}{i^2_{max}}
\]
\[\therefore x_{min} = i_{max}b = \frac{n}{i_{max}}
\]
\[\because k < \frac{n}{x_{min}}
\]
\[\therefore k < i_{max}
\]
\[\because ans = k - 1
\]
\[\therefore ans = i_{max} - 1
\]
\[\therefore ans = ans\times 8(正方形,四个角,直角在两边)
\]
\[证毕
\]
代码
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define int long long
using namespace std;
const int maxn = 1e5 + 50, INF = 0x3f3f3f3f;
inline int read () {
register int x = 0, w = 1;
register char ch = getchar ();
for (; ch < '0' || ch > '9'; ch = getchar ()) if (ch == '-') w = -1;
for (; ch >= '0' && ch <= '9'; ch = getchar ()) x = x * 10 + ch - '0';
return x * w;
}
inline void write (register int x) {
if (x / 10) write (x / 10);
putchar (x % 10 + '0');
}
int n, ans;
signed main () {
freopen ("tri.in", "r", stdin);
freopen ("tri.out", "w", stdout);
while (1) {
n = read();
if (n == 0) break;
for (register int i = 1; i * i <= n; i ++) {
if (n % (i * i) == 0) ans = (i - 1) * 8;
}
printf ("%lld\n", ans);
}
return 0;
}