zoukankan      html  css  js  c++  java
  • [2015编程之美] 资格赛C

    #1150 : 基站选址

    时间限制:2000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    需要在一个N × M的网格中建立一个通讯基站,通讯基站仅必须建立在格点上。

    网格中有A个用户,每个用户的通讯代价是用户到基站欧几里得距离的平方。

    网格中还有B个通讯公司,维护基站的代价是基站到最近的一个通讯公司的路程(路程定义为曼哈顿距离)。

    在网格中建立基站的总代价是用户通讯代价的总和加上维护基站的代价,最小总代价。

    输入

    第一行为一个整数T,表示数据组数。

    每组数据第一行为四个整数:N, M, A, B。

    接下来的A+B行每行两个整数x, y,代表一个坐标,前A行表示各用户的坐标,后B行表示各通讯公司的坐标。

    输出

    对于每组数据输出一行"Case #X: Y",X代表数据编号(从1开始),Y代表所求最小代价。

    数据范围

    1 ≤ T ≤ 20

    1 ≤ x ≤ N

    1 ≤ y ≤ M

    1 ≤ B ≤ 100

    小数据

    1 ≤ N, M ≤ 100

    1 ≤ A ≤ 100

    大数据

    1 ≤ N, M ≤ 107

    1 ≤ A ≤ 1000

    样例输入
    2
    3 3 4 1
    1 2
    2 1
    2 3
    3 2
    2 2
    4 4 4 2
    1 2
    2 4
    3 1
    4 3
    1 4
    1 3
    样例输出
    Case #1: 4
    Case #2: 13

    模拟退火,死活过不了,贴一个Wa代码,望路过大神指正
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <ctime>
    #include <cstdlib>
    using namespace std;
    #define ll long long
    #define INF 1e40
    #define PI acos(-1.0)
    #define N 1010
    
    struct Point
    {
        double x,y;
        Point(){}
        Point(double x,double y):x(x),y(y){}
    };
    int n,m;
    double lx,ly;
    Point p[N],q[N];
    int dir[9][2]={0,1,0,-1,1,0,-1,0,-1,-1,1,1,-1,1,1,-1,0,0};
    
    double cal(Point t)
    {
        double sum=INF;
        for(int i=1;i<=m;i++) sum=min(sum,fabs(q[i].x-t.x)+fabs(q[i].y-t.y));
        for(int i=1;i<=n;i++) sum+=(p[i].x-t.x)*(p[i].x-t.x)+(p[i].y-t.y)*(p[i].y-t.y);
        return sum;
    }
    void solve()
    {
        int TN=4,DN=50;
        Point u,v,ansp;
        double ud,vd,ansd=INF;
        double step=sqrt(lx*lx+ly*ly),eps=1e-4,r=0.95;
    
        while(TN--)
        {
            u=Point(rand()%int(lx),rand()%int(ly));
            ud=cal(u);
            ud=cal(u);
            while(step>eps)
            {
                bool flag=1;
                while(flag)
                {
                    flag=0;
                    for(int i=0;i<DN;i++)
                    {
                        double d=2*PI*(double)rand()/RAND_MAX;
                        v.x=u.x+sin(d)*step;
                        v.y=u.y+cos(d)*step;
                        if(v.x<0 || v.x>lx || v.y<0 || v.y>ly) continue;
                        vd=cal(v);
                        if(vd<ud) ud=vd,u=v,flag=1;
                    }
                }
                step*=r;
            }
            if(ud<ansd) ansd=ud,ansp=u;
        }
        double ans=INF;
        for(int i=0;i<9;i++)
        {
            int x=(int)ansp.x+dir[i][0];
            int y=(int)ansp.y+dir[i][1];
            if(x<0 || x>lx || y<0 || y>ly) continue;
            double tt=cal(Point(x,y));
            ans=min(ans,tt);
        }
        printf("%.0f
    ",ans);
    }
    int main()
    {
        int T,iCase=1;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%lf%lf%d%d",&lx,&ly,&n,&m);
            for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
            for(int i=1;i<=m;i++) scanf("%lf%lf",&q[i].x,&q[i].y);
            printf("Case #%d: ",iCase++);
            solve();
        }
        return 0;
    }
    趁着还有梦想、将AC进行到底~~~by 452181625
  • 相关阅读:
    MyEclipse 使用快捷键
    修改MyEclipse默认的Servlet和jsp代码模板
    设置MyEclipse开发项目时使用的JDK
    65.广搜练习:细胞数目
    65.广搜练习:细胞数目
    61.新的开始(最小生成树)
    61.新的开始(最小生成树)
    66.广搜练习:最少关卡路
    66.广搜练习:最少关卡路
    64.广搜练习跳马问题
  • 原文地址:https://www.cnblogs.com/hate13/p/4472720.html
Copyright © 2011-2022 走看看