HDU 4355 Party All The Time——三分搜索

  • 链接:http://acm.hdu.edu.cn/showproblem.php?pid=4355
  • 题意:给定一些点的位置和他们的权重,计算一个目的地,使得所有点到这个目的地的函数值之和最小。函数值为 距离之差的立方 * w。
  • 分析: 此题应该是裸的三分搜索的模板题,因为题中说明,每个点的位置是按照 x[i] <= x[i+1] 输入的,所以三分搜索的边界 l = x[0], r = x[N-1]。因为是小数点后一位的位置,所以EPS 精确到 1e-4即可。
    Notes: 如果三分搜索不懂的话,看此文章

https://blog.csdn.net/qq_39763472/article/details/105061044

  • 代码:
#include "bits/stdc++.h"
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define mk make_pair
typedef long long ll;
const int maxn = 1e5 + 7;
const int INF = 0x3f3f3f;
const double EPS = 1e-4;
int t,N;
struct Point{
    
    
    double weigh,pos;
    Point(double w,double p):weigh(w),pos(p){
    
    };
};
vector<Point> vp;
double com(double pos){
    
    
    double ans = 0.0;
    for (int i = 0; i < N; i++) {
    
    
        double dis = fabs(vp[i].pos - pos);
        double w = vp[i].weigh;
        ans += pow(dis,3)*w;
    }
    return ans;
}
int main(){
    
    
    // freopen("1.txt","r",stdin);
    ios::sync_with_stdio(0);
    cin.tie(0);
    scanf("%d",&t);
    for (int kase = 1; kase <= t; kase++) {
    
    
        scanf("%d",&N);
        vp.clear();
        double w,p;
        for (int i = 0; i < N; i++) {
    
    
            scanf("%lf%lf",&p,&w);
            vp.pb(Point(w,p));
        }
        double l = vp[0].pos, r = vp[N-1].pos;
        while (r - l > EPS) {
    
    
            double midl = l + (r - l)/3;
            double midr = r - (r - l)/3;
            if (com(midl) > com(midr)) {
    
    
                l = midl;
            }else r = midr;
        }
        int ans = floor(com(l) + 0.5);
        cout<<"Case #"<<kase<<": "<<ans<<endl;
    }
    return 0;
}

  • 遇到的问题:
    (1)cin会wa。虽然用cin.tie(0) 以及 sync_with_stdio(0)取消了cin和stdin的同步,但是这样会使得cin的速度接近于scanf,在数据较大时,还是需要使用scanf 和printf!
    (2)关于 四舍五入, 英文是 nearest integer,最近的整数。用刘汝佳大神告知我们的 floor取整函数, 即 floor(ans + 0.5) 来做到四舍五入。

猜你喜欢

转载自blog.csdn.net/qq_39763472/article/details/105073536