杨辉三角形

杨辉三角形

题目描述#

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

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

输入描述#

输入一个整数 N。

输出描述#

输出一个整数代表答案。

输入输出样例#

示例 1

输入

6

输出

13

评测用例规模与约定#

对于 20 的评测用例,1≤N≤10​; 对于所有评测用例,1≤N≤1000000000。

运行限制#

  • 最大运行时间:1s
  • 最大运行内存: 256M

分析#

杨辉三角对称,因此我们只要算一半的数即可(算全部的TLE),用两个数组维护上一状态和这一状态的数,然后在快速判断这个数第一次是否只出现在n行的第二个数即可。 说明一下这个最高循环次数,我们通过观察不难发现,如果某一行的第二个数是n,那么第三个数就绝对是n(n-1)/2,因此,当n=44732的时候,第三个数绝对是44732x44731/2 = 1,000,453,546 > 10亿,你第三个数都已经大于10亿了,杨辉三角除了第二个数外其他都是递增的,说明小于10亿的前面都已经算了,以后除了每行的第二个数,你还有必要算么?

提交答案#

#include <iostream>
using namespace std;
long long a[100010],b[100010];//开两个数组,一个保存上一行那一半的数,一个保存目的行那一半的数
int main()
{
  a[0]=1;
  b[0]=1;
  long long n;
  cin>>n;
  if(n==1){
    cout<<1;
    return 0;
  }
  for(int i=3;i<=44723;i++){//这个是最高循环次数,你可以自己找
    int m=i/2;//只要一半
    for(int j=1;j<=m;j++){
        if(j==m&&i%2==1){//如果行数为奇数那么就有个中间数,就是上一行前面数的两倍
            b[j]=a[j-1]*2;
        }
        else{
            b[j]=a[j-1]+a[j];//杨辉三角
        }
        a[j-1]=b[j-1];//更新a数组
        if(b[j]==n){//i是行数,j是第i行的第几个数
            cout<<i*(i-1)/2+j+1;//输出 用查询第6行第3个数10为例子来理解,6*(6-1)/2+2+1=18,即10第一次出现是在第18个数
            return 0;
        }
    }
    a[m]=b[m];//更新a数组
    if(b[1]>n){//快速判断,我们想想,在没找到目的数之前,如果有一行的第二个数比目的数还要大,那么肯定就不会再次出现,直接快速判断输出结果为n行的第二个数。
        cout<<n*(n+1)/2+2;//如果某一行的数比目的数还要大,直接快速判断输出结果为n行的第二个数 用查询第4行第2个数3为例子来理解,第5行第2个数是4比3大,那么直接输出3这个数第一次出现是在第3*(3+1)/2+2=8个数
        return 0;
    }
  }
  cout<<n*(n+1)/2+2;//防止溢出
  return 0;
}
#include<bits/stdc++.h>
using namespace std;
long long a[100010],b[100010];
int main()
{
	a[0]=1;
	b[0]=1;
	long long n;
	cin>>n;
	if(n==1)
	{
		cout<<1;
		return 0;
	}
	for(int i=3;i<=44723;i++)
	{
		int m=i/2;
		for(int j=1;j<=m;j++)
		{
			if(j==m&&i%2==1)
			{
				b[j]=a[j-1]*2;
			}
			else
			{
				b[j]=a[j-1]+a[j];
			}
			a[j-1]=b[j-1];
			if(b[j]==n)
			{
				cout<<i*(i-1)/2+j+1;
				return 0;
			}
		}
		a[m]=b[m];
		if(b[1]>n)
		{
			cout<<n*(n+1)/2+2;
			return 0;
		}
	}
	cout<<n*(n+1)/2+2;
	return 0;
}
posted @   bujidao1128  阅读(99)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示
主题色彩