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) 來做到四捨五入。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章