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

在这里插入图片描述
【题意分析】

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

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

在这里插入图片描述
那么正方形就是一层一层地摆下来的,那么接下来有两种求法:

每一层比前一层多摆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根

在这里插入图片描述
接下来一段都是两根一个:

在这里插入图片描述
下面这个是三根:

在这里插入图片描述
剩下的一段全都是两根一个:

在这里插入图片描述
这样就好了,每次询问回答是 O ( 1 ) O(1) O(1)

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

Code:

#pragma GCC optimize (2)
#pragma GCC optimize ("Ofast")
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值