题面:
解析:通过暴力加剪枝可过,代码如下:
#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define sc(x) scanf("%d",&x)
#define pr(x) printf("%d\n",x)
#define rep(i, l, r) for (int i = (l); i <= (r); i++)
typedef long long ll;
const int mod = 1e9+7;
int main()
{
/*ll n=1;
while(n++){
ll m=n;
double x=1;
for(int i=1;i<=n/2;i++){
x*=1.0*m/i;
m--;
}
printf("%.0lf,",x);
if(x>=1000000000) break;
}*/
ll arr[]={1,1,2,3,6,10,20,35,70,126,252,462,924,1716,3432,6435,12870,24310,48620,92378,184756,352716,705432,
1352078,2704156,5200300,10400600,20058300,40116600,77558760,155117520,300540195,601080390,1166803110};
ll n;
while(~scanf("%lld",&n)){
ll m=0,x,y; //x代表n所在的行号,y表示n在这行的位置,则n第一次出现在:x*(x+1)/2+y
while(n>arr[m]){ //查找出n可能所在的最小行,则x的范围为:m~n
m++;
}
//printf("%d\n",m);
if(arr[m]==n){
x=m;
y=m/2+1;
}
else{
ll z=m/2;
for(ll i=m;i<=n;i++){
double ns=1.0;
int nm=i;
for(ll j=1;j<=z;j++){
ns*=1.0*nm/j;
nm--;
}
if(ns>n) z--; //确定y的取值
if(z==1) {
x=n-1;
y=2;
break;
}
if(ns==n) {
x=i;
y=z+1;
break;
}
}
}
//printf("%d %d\n",x,y);
ll ans=0;
ans=(x)*(x+1)/2+y;
printf("%lld\n",ans);
}
return 0;
}