Shell Pyramid题解
题目不放了,英文看着没啥意思,简化后就是: 给你很多堆球(如上),然后他会给一个数字N,询问第N个球在第几堆,在该堆的第几行第几个
测试用例
cin
2
19
75822050528572544
cout
4 4 3
769099 111570 11179
划重点了!
想法很简单,记录两个数组,a数组用于记录一堆球在某一行时(仔细想想,可能表达的不是很清楚),共有多少个球(1、3、6、10……),在确定了球在第几堆后,用a数组来判定具体位置
sum数组用于记录到第几堆时,共有多少个球(1、4、10、20……)
- 在拿到数字后,我们采用二分查找函数【lower_bound(数组开头,数组结尾,要找的数)-数组】
ll ans1 = lower_bound(sum,sum+maxn,number)-sum;,该函数会返回一个大于等于参数val的序列值的迭代器(我上一篇博客有----stl迭代器中的二分查找),也就找到了第N个球在第几组里; - 此时要进行一个操作,减去前面所有的球(比如查找到在第四组,那么就要减去前面三组的球,看还剩下多少球,从而利用a数组确定球在第四组的位置)number = number -sum[ans1-1]
- 然后同样的方法确定在第几行,如果确定在第四行,那么要减去前三行的球,剩下的数,就是在第四行的位置了,对吧 ll ans3 = number - a[ans2-1];
到此为止完事了,输出即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+5;
typedef long long ll;
int i,t;
ll a[maxn];
ll sum[maxn];
int main()
{
ios::sync_with_stdio(false);//用于关闭cin和cout的同步,使得cin和cout效率与scanf、prinft差不多,这个题里这行没啥用,写习惯了
a[1]=1;
for(i=2;i<maxn;i++)
{
a[i]=a[i-1]+i;
}
sum[1]=1;
for(i=2;i<maxn;i++)
{
sum[i]=sum[i-1]+a[i];
}
cin>>t;
while(t--)
{
ll number;
cin>>number;
ll ans1 = lower_bound(sum,sum+maxn,number)-sum;
number = number - sum[ans1-1];
ll ans2 = lower_bound(a,a+maxn,number)-a;
ll ans3 = number - a[ans2-1];
cout<<ans1<<" "<<ans2<<" "<<ans3<<endl;
}
return 0;
}
- 下面我会拿一个例子来解析一下,答案是怎么出来的(因为我当初菜的时候,看到大神的代码只是往上面一贴,也不讲,很难看懂,所以不想让后来人也像当初的我一样狼狈)
cin>>19
我们取到需要用到的a和sum数组
a【1】=1
a【2】=3
a【3】=6
a【4】=10
sum【1】=1
sum【2】=4
sum【3】=10
sum【4】=20
(1)在ll ans1 = lower_bound(sum,sum+maxn,number)-sum;过程中,Lower_bound返回第一个大于等于参数val的序列值的迭代器,也就是4
(2)下一步,我们确定了在第四堆,那么第四堆有多少球?number = number - sum[ans1-1]; 把19-10赋给number
(3)然后确定9在一个三角形球堆中的位置,
ll ans2 = lower_bound(a,a+maxn,number)-a;这就不讲了,答案是4
(4)第四排有几个球?用此时的number减去前三排的球,把9-6赋给ans3
ll ans3 = number - a[ans2-1];
(5)输出