今天见识到了一个叫做二分算法的东西,是在洛谷上见到的。
题目如下:
题目所要求的就是一个枚举或者之类的算法,对我来说,就是一个计算的过程,将每一项的数值计算出来。
我第一次的草稿就是设立了多个变量,表示了斜列数,分子数值,分母数值。然后,通过列数求和的方式求出第N项所在的列数和排位在哪。接着判断列数是奇数还是偶数来确定分母分子的大小。
代码如下,
#include
using namespace std;
int main() {
int N;
cin >> N;
int n = 0, t = 0;
while (t < N) {
n++;
t += n;
}
cout << “这是第” << n << “组第” << N - t + n << “个”;
if (n % 2 == 0) cout << N - t + n << “/” << t - N + 1;
else cout << t - N + 1 << “/” << N - t + n;
return 0;
}
但是运行的时候超时了。不过这个代码思路比较简单,所以容易想到。
下面的二分法代码有些意思,虽然看起来比我的代码长,不过运行的速度更快。
#include
#include
using namespace std;
int main(){
long long l=1,r,mid,n,a;
cin>>n;
r=n;
while(l<r){
mid=(l+r)/2;
if(mid*(mid+1)/2<n)l=mid+1;
else r=mid;
}
a=n-l*(l-1)/2;
if(l%2==0)cout<<a<<’/’<<l+1-a;
else cout<<l+1-a<<’/’<<a;
return 0;
}
第i斜列,每一列的元素个数包含的项的次序为i*(i-1)/2+1到i*(i+1)/2。while循环在使用二分法的概念进行筛选,mid左侧的数总和小于n时就将左端向右靠一位,总和大于n时,将右端向左靠,来一次次的缩小范围,最后得到的l就是我们需要的行数。
然后判断一次所在斜列是奇数列还是偶数列,以此将最后得到的结果输出出来。