[洛谷模拟赛T2]画地为佬——[简单数学]

[洛谷模拟赛T2]画地为佬——[简单数学]_第1张图片
【题意分析】

题意:用 n n n根火柴棒最多可以摆成几个正方形,不一定要用完火柴棒

首先明确摆法是贴着边一个一个摆下来的,摆法有很多而且都是等价的,我是这么摆的:

[洛谷模拟赛T2]画地为佬——[简单数学]_第2张图片
那么正方形就是一层一层地摆下来的,那么接下来有两种求法:

每一层比前一层多摆4根火柴,那么根据数列知识:

a 1 = 4 , a n + 1 − a n = 4 ( n ∈ N ∗ ) a_1=4,a_{n+1}-a_n=4(n\in \N ^*) a1=4,an+1an=4(nN)

⇒ S n = 2 n 2 + 2 n \Rightarrow S_n=2n^2+2n Sn=2n2+2n

或者直接观察:前n层火柴总和就是 2 ∗ n ∗ ( n + 1 ) = 2 n 2 + 2 n 2*n*(n+1)=2n^2+2n 2n(n+1)=2n2+2n

那么我们需要解出给你的火柴根数最多可以摆出几层。

2 n 2 + 2 n ≥ x 2n^2+2n\geq x 2n2+2nx

⇒ n ≥ − 2 + 4 + 8 x 4 \Rightarrow n\geq\frac{-2+\sqrt{4+8x}}{4} n42+4+8x

那你floor一下就好了,我们设这个层数为n

求出剩下还有 x − ( 2 n 2 + 2 n ) x-(2n^2+2n) x(2n2+2n)根火柴

接下来你就分类讨论:因为开始的那个正方形需要3根

[洛谷模拟赛T2]画地为佬——[简单数学]_第3张图片
接下来一段都是两根一个:

[洛谷模拟赛T2]画地为佬——[简单数学]_第4张图片
下面这个是三根:

[洛谷模拟赛T2]画地为佬——[简单数学]_第5张图片
剩下的一段全都是两根一个:

[洛谷模拟赛T2]画地为佬——[简单数学]_第6张图片
这样就好了,每次询问回答是 O ( 1 ) O(1) O(1)

时间复杂度 O ( T ) O(T) O(T)

Code:

#pragma GCC optimize (2)
#pragma GCC optimize ("Ofast")
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define int long long
using namespace std;

inline int read () {
	register int s = 0, w = 1;
	register char ch = getchar ();
	while (! isdigit (ch)) {if (ch == '-') w = -1; ch = getchar ();}
	while (isdigit (ch)) {s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar ();}
	return s * w;
}

signed main () {
	int T = read ();
	for (register int I = 1; I <= T; ++I) {
		int x = read (), layer = floor ((double) ((sqrt (4 + 8 * x) - 2) / 4));
		if (x <= 4) {printf ("%d\n", x / 4); continue;}
		x -= 2 * layer * layer + 2 * layer; int res = layer * layer;
		if (x <= 2) printf ("%lld\n", res);
		else if (x <= 3 + (layer - 1) * 2) printf ("%lld\n", res + 1 + (x - 3) / 2);
		else if (x < 6 + (layer - 1) * 2) printf ("%lld\n", res + layer);
		else if (x == 6 + (layer - 1) * 2) printf ("%lld\n", res + layer + 1);
		else printf ("%lld\n", res + (x - 6) / 2 + 2);
	}
	return 0;
}

你可能感兴趣的:(数学,模拟)