上午小测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;
}
posted @ 2020-10-28 12:00  Rubyonlу  阅读(112)  评论(1编辑  收藏  举报