题意:f(m) = m*(m+1)/2. 找到最大的 f(m),使 f(m) <= N. 输出这个 f(m)。
直接解方程就可以,需要注意的是开根号过程中会出现精度问题,我们在解出来的 m 的附近找一小范围就可以。
#include<cstring> #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> using namespace std; int main(){ //freopen("a.txt", "r", stdin); int t; cin >> t; for(int cas = 1; cas <= t; cas++){ long long n; scanf("%lld", &n); long long m = (long long)((sqrt(1+8.0*n)-1)/2); m += 2; while(1){ long long k = m*(m+1)/2; if(k<=n){ printf("Case #%d: %lldn", cas, k); break; } m--; } } return 0; }
还有一种方法,二分,找到最大的 m 满足 f(m) > n. 注意下精度问题即可。
#include<cstring> #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> using namespace std; long long n; long long f(long long x){ return x*(x+1)/2; } bool judge(long long x){ if(f(x) > n) return 1; return 0; } int main(){ //freopen("a.txt", "r", stdin); int t; cin >> t; for(int cas = 1; cas <= t; cas++){ scanf("%lld", &n); long long l = 1, r = 1e10; while(l <= r){ long long mid = l+(r-l)/2; if(judge(mid)) r = mid-1; else l = mid+1; } //cout << l << endl; //cout << r << endl; l = f(--l); printf("Case #%d: %lldn", cas, l); } return 0; }