第十二届蓝桥杯省赛 C++ B组 - 杨辉三角形

✍个人博客:https://blog.csdn.net/Newin2020?spm=1011.2415.3001.5343
📚专栏地址:蓝桥杯题解集合
📝原题地址:杨辉三角形
📣专栏定位:为想参加蓝桥杯的小伙伴整理常考算法题解,祝大家都能取得理想成绩!
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

问题描述

下面的图形是著名的杨辉三角形
如果我们按从上到下、从左到右的顺序把所有数排成一列,可以得到如下数列:
1, 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, 4, 6, 4, 1, …
给定一个正整数 N,请你输出数列中第一次出现 N 是在第几个数?
输入格式
输入一个整数 N。
输出格式
输出一个整数代表答案。
数据范围
对于 20% 的评测用例,1≤N≤10;
对于所有评测用例,1≤N≤109
输入样例
6
输出样例
13

思路

这道题如果想要得满分,需要一点小技巧,详细步骤:
(1)我们先把杨辉三角形平均分成两半,因为在右半边的内容一定也会出现在左半边,所以我们只用看左半边,然后找规律即可。
请添加图片描述
(2)通过上图可以发现每个斜行从右上到左下都是递增的,并且每行从左到右也是递增的。故每个斜行的第一个元素一定是该元素出现的第一个位置,只要从最下面的那个斜行开始枚举,就能找到目标元素。
在这里插入图片描述
(3)那么我们接下来要找到前多少个斜行能够包含到最大值 109,通过计算 C1734 要大于 109,并且 C1632 要小于 109 。所以我们只用从第 16 斜行开始往下枚举即可。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL n;

//求组合数
LL C(LL a, int b)
{
	LL res = 1;
	for (int i = a, j = 1; j <= b; i--, j++)
	{
		res = res * i / j;
		if (res > n)	return res;
	}
	return res;
}

bool check(int k)
{
	//下限是2*k,上限最差是n,当k=1时,C(n,1)=n
	LL l = 2 * k, r = max(n, l);
	while (l < r)
	{
		LL mid = l + r >> 1;
		if (C(mid, k) >= n)	r = mid;
		else l = mid + 1;
	}
	if (C(r, k) != n)	return false;
	//下标为r的位置前面有r+1行(等差公式得r*(r+1)/2)
	cout << (LL)r * (r + 1) / 2 + k + 1 << endl;
	return true;
}

int main()
{
	cin >> n;
	//从最大的斜行往前枚举
	for (int k = 16;; k--)
		if (check(k))
			break;
	return 0;
}
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值