8

2015ACM-ICPC亚洲区域赛EC-Final A:Boxes and Balls

 3 years ago
source link: https://arminli.com/ec-final-a/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Armin's Blog

2015ACM-ICPC亚洲区域赛EC-Final A:Boxes and Balls

February 26, 2016

题目 PDF 下载

题意: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;
}

Profile picture

Written by Armin Li , a venture capitalist. [Weibo] [Subscribe]


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK