题面:B组alt

解析:通过暴力加剪枝可过,代码如下:

#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;
}