[找规律][二分]杨辉三角 2021年蓝桥杯

23 篇文章 0 订阅
16 篇文章 0 订阅

题目描述

下面的图形是著名的杨辉三角形:

如果我们按从上到下、从左到右的顺序把所有数排成一列,可以得到如下
数列:
1, 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, 4, 6, 4, 1, ...
给定一个正整数 N,请你输出数列中第一次出现 N 是在第几个数?

输入

输入一个整数 N。

输出

输出一个整数代表答案。

样例输入

6

样例输出

13

提示

【评测用例规模与约定】
对于 20% 的评测用例,1 ≤ N ≤ 10;
对于所有评测用例,1 ≤ N ≤ 1000000000。

题意: 在杨辉三角中找到第一个出现n的位置。

分析: 多画几行杨辉三角找找规律:

由于左右对称,右边出现的数字不如左边更优,于是只考虑三角形左侧部分。然后斜着看这些数字,可以把这些数字分成若干组,每组内部递增,这启发我们用二分的方法去找n,于是从最右侧的条带上二分,之所以从这条开始是因为从这条上找到的n会其它位置都更优,这条条带二分完后再到左边一个上面二分,直至第一次找到n,在所有条带前1e9个数字内一定会出现n,于是二分的范围也就确定了。

具体代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#define int long long
using namespace std;
//只考虑左侧且斜着看
//第i斜条的起始元素为C(2*(i-1), i-1)
//每一斜条的第k元素就是C(2*(i-1)+k-1, i-1) 
int n;

int c(int a, int b)//直接暴力求组合数 
{
	if(b > a-b) b = a-b;
	int ans = 1;
	for(int i = 1; i <= b; i++)
	{
		ans = ans*(a-i+1)/i;
		if(ans > n)//防止越界 
			return n+1; 
	}
	return ans;
} 
 
signed main()
{
	cin >> n;
	if(n == 1)
		cout << 1;
	else
	{
		for(int i = 16; i >= 1; i--)
		{
			int l = 2*i, r = 1000000000, ans = -1;
			while(l <= r)
			{
				int m = l+r>>1;
				if(c(m, i) >= n)
				{
					ans = m;
					r = m-1;
				}
				else
					l = m+1;
			}
			if(ans != -1 && c(ans, i) == n)
			{
				cout << (1+ans)*ans/2+i+1;
				break;
			}
		}
	}
    return 0;
}

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
蓝桥杯是中国最具影响力的计算机科学与技术竞赛之一,旨在培养和选拔优秀的计算机人才。而杨辉三角蓝桥杯中常见的一个题目类型,它是一个数学上的三角形,其中的数字具有一定的规律性。 杨辉三角的构造规则如下: 1. 第一行只有一个数字1。 2. 第二行两个数字都是1。 3. 从第三行开始,每个数字都是它上方两个数字之和。 以下是一个示例的杨辉三角: ``` 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 ``` 在C语言中,可以使用二维数组来表示和打印杨辉三角。具体实现可以参考以下代码: ```c #include <stdio.h> void printYanghuiTriangle(int n) { int triangle[n][n]; // 初始化杨辉三角的第一列和对角线上的元素为1 for (int i = 0; i < n; i++) { triangle[i] = 1; triangle[i][i] = 1; } // 计算其他位置上的元素 for (int i = 2; i < n; i++) { for (int j = 1; j < i; j++) { triangle[i][j] = triangle[i-1][j-1] + triangle[i-1][j]; } } // 打印杨辉三角 for (int i = 0; i < n; i++) { // 打印每行前的空格 for (int k = 0; k < n - i - 1; k++) { printf(" "); } // 打印每个数字 for (int j = 0; j <= i; j++) { printf("%d ", triangle[i][j]); } printf("\n"); } } int main() { int n; printf("请输入杨辉三角的行数:"); scanf("%d", &n); printYanghuiTriangle(n); return 0; } ``` 这段代码可以根据用户输入的行数打印相应行数的杨辉三角。你可以尝试运行这段代码,并输入一个正整数来查看结果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值