D. Pythagorean Triples(1487D)(打表找规律 + 二分)

D. Pythagorean Triples(1487D)(打表找规律 + 二分)


题目来源:D. Pythagorean Triples


题意:

给定一个 n,求满足以下条件的数对 (a, b, c) 的个数

  • 1 <= a <= b <= c <= n
  • a * a + b * b = c * c
  • c = a * a - b

思路:

这个题推公式也可以求,但当时太菜了没想到,而且题目还理解错了

通过打表我们发现(刚开始表还打错了

  • n = 1 ~ 4, ans = 0
  • n = 5 ~ 12, ans = 1
  • n = 13 ~ 24, ans = 2
  • n = 24 ~ 40, ans = 3
  • n = 41 ~ 60, ans = 4

我们去记录最后一个数字会发现,他们相邻两个数之间的差为 8, 12, 16, …是公差为 4 的等差数列

我们记差值 a[i] = 8 + 4 * (i - 1), 其中 a[0] = 0, 那么答案为 i 所对应的最大的 n 就是 a 的前 i 项和再加 4(最开始的1 ~ 4没有算),也就是x = i * (8 + 8 + 4 * (i - 1)) / 2 + 4 = 2 * i * i + 6 * i + 4

我们去二分枚举出离 n 最近,并且大于等于 n 的 x, 最后输出 x 所对应的 i 即可

  • 等差数列前 i 项和:项数 * (首项 + 末项) / 2

AC代码

#include <bits/stdc++.h>
#define endl "\n"
#define rep(i, m, n) for (int i = (m); i <= (n); ++i)
#define rrep(i, m, n) for (int i = (m); i >= (n); --i)
#define IOS ios::sync_with_stdio(0); cin.tie(0);
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = +10, mod = 1e9 + 7;
int n;
//等差数列前x项和 + 4
ll fact(ll x) { return (2 * x * x + 6 * x) + 4; }
void solve() {
	cin >> n;
	int l = 0, r = 1e6;
	while (l < r) {
		ll mid = l + r >> 1;
		if (fact(mid) >= n) r = mid;
		else l = mid + 1;
	}
	printf("%d\n", l);
}
int main() {
	int t; cin >> t;
	while (t--) solve();
	return 0;
}

END

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值