• hihocoder 2015编程之美 资格赛 hihocoder 第三题 基站选址


    http://hihocoder.com/contest/msbop2015qual/problem/3

    O(n)的时间和空间开销

    看似是图论,实际是数论。

    关键点1:基站  “欧几里得距离的平方”  优先级远大于  “ 曼哈顿距离”  只需考虑欧几里德距离平方最小的坐标即可

    关键点2:欧几里德距离平方,x轴y轴可分离讨论。变成两个 “一维上到各点欧几里德平方和最小的点” 

    ∑[(Xn-X0)2+(Yn-Y0)2]=∑(Xn-X0)2+∑(Yn-Y0)2

    关键点3:“一维上到各点欧几里德平方和最小的点”  =》  ∑(xn-x02  =Σ(Xn2)+nX- 2X∑(Xn)  最小

    问题变成,求二元一次方程组最小解的横坐标

    最后:

    X0= ∑(Xn)/n;

    Y0= ∑(Yn)/n;

    (因为要求 “通讯基站仅必须建立在格点上”  所以需要对最近的四个点进行判定(x+y)(x,y+1)(x+1,y)(x+1,y+1))

    然后 “ 最小曼哈顿距离”的时候,xy是不可分离的,但因为关键点1 也只需要对上面四个点遍历一次就可以获得最终解

    80行代码 出去头尾声明引用,中间的空行,可能也就60+行

     1 #include <iostream>
     2 #include <vector>
     3 #include <string>
     4 #include <vector>
     5 #include <math.h>
     6 using namespace std;
     7 #define modnum 100007
     8 long long cost=0;
     9 long long maxll=9223372036854775807;
    10 long long mincost=maxll;
    11 long long totalAx=0;
    12 long long totalAxSquare=0;
    13 long long totalAy=0;
    14 long long totalAySquare=0;
    15 vector<long long> bx;
    16 vector<long long> by;
    17 int N,M,A,B;
    18 long long cal(long long totalSquare,long long total,long long x,long long num) 19 { 20 long long ans=0; 21 ans+=totalSquare+num*x*x-2*total*x; 22 return ans; 23 } 24 long long calAll(long long x,long long y) 25 { 26 long long ans=maxll; 27 for(int i=0;i<bx.size();i++) 28 { 29 ans=min(ans,abs(bx[i]-x)+abs(by[i]-y)); 30 } 31 return ans+cal(totalAxSquare,totalAx,x,A)+cal(totalAySquare,totalAy,y,A); 32 } 33 int main() 34 { 35 36 int T=0; 37 int Case=0; 38 cin>>T; 39 while(T) 40 { 41 bx.clear(); 42 by.clear(); 43 totalAx=0; 44 totalAxSquare=0; 45 totalAy=0; 46 totalAySquare=0; 47 48 T--; 49 Case++; 50 51 cin>>N>>M>>A>>B; 52 int temp=0; 53 for(int i=0;i<A;i++) 54 { 55 cin>>temp; 56 totalAx+=temp; 57 totalAxSquare+=temp*temp; 58 cin>>temp; 59 totalAy+=temp; 60 totalAySquare+=temp*temp; 61 } 62 for(int i=0;i<B;i++) 63 { 64 cin>>temp; 65 bx.push_back(temp); 66 cin>>temp; 67 by.push_back(temp); 68 } 69 long long x,y; 70 x=totalAx/A; 71 y=totalAy/A; 72 long long ans=maxll; 73 ans=min(ans,calAll(x,y)); 74 ans=min(ans,calAll(x,y+1)); 75 ans=min(ans,calAll(x+1,y)); 76 ans=min(ans,calAll(x+1,y+1)); 77 78 cout<<"Case #"<<Case<<": "<<ans<<endl; 79 } 80 }

     以上代码有个问题。。

    第52行  int temp=0;
    int在大数据的时候10^7的数据大小是可以正常输入的
    但,第57 60行,temp*temp直接导致数据溢出了。。

    以下是通过大数据的算法 其实就是把int temp 改成了long long temp

    以下代码已通过大数据测试

     1 #include <iostream>
     2 #include <vector>
     3 #include <string>
     4 #include <vector>
     5 #include <math.h>
     6 using namespace std;
     7 #define modnum 100007
     8 long long cost=0;
     9 long long maxll=9223372036854775807;
    10 long long mincost=maxll;
    11 long long totalAx=0;
    12 long long totalAxSquare=0;
    13 long long totalAy=0;
    14 long long totalAySquare=0;
    15 vector<long long> bx;
    16 vector<long long> by;
    17 int N,M,A,B;
    18 long long cal(long long totalSquare,long long total,long long x,long long num) 
    19 {
    20     long long ans=0;
    21     ans+=totalSquare+num*x*x-2*total*x;
    22     return ans;
    23 }
    24 long long calAll(long long x,long long y)           
    25 {
    26     long long ans=maxll;
    27     for(int i=0;i<bx.size();i++)
    28     {
    29         ans=min(ans,abs(bx[i]-x)+abs(by[i]-y));      
    30     }
    31     return ans+cal(totalAxSquare,totalAx,x,A)+cal(totalAySquare,totalAy,y,A);   
    32 }
    33 int main()
    34 {
    35     
    36     int T=0;
    37     int Case=0;
    38     cin>>T;
    39     while(T)
    40     {
    41         bx.clear();
    42         by.clear();
    43         totalAx=0;
    44         totalAxSquare=0;
    45         totalAy=0;
    46         totalAySquare=0;
    47         
    48         T--;
    49         Case++;
    50 
    51         
    52         cin>>N>>M>>A>>B;
    53         long long ans=maxll;
    54         long long temp=0;
    55         for(int i=0;i<A;i++)      
    56         {
    57             cin>>temp;
    58             totalAx+=temp;
    59             totalAxSquare+=temp*temp;
    60             cin>>temp;
    61             totalAy+=temp;
    62             totalAySquare+=temp*temp;
    63         }
    64         for(int i=0;i<B;i++)
    65         {
    66             cin>>temp;
    67             bx.push_back(temp);
    68             cin>>temp;
    69             by.push_back(temp);
    70         }
    71         long long x,y;
    72         x=totalAx/A;          
    73         y=totalAy/A;
    74         ans=min(ans,calAll(x,y+1));
    75         ans=min(ans,calAll(x+1,y));
    76         ans=min(ans,calAll(x+1,y+1));
    77         ans=min(ans,calAll(x,y));
    78 
    79         cout<<"Case #"<<Case<<": "<<ans<<endl;
    80     }
    81 }
  • 相关阅读:
    递归遍历树形json
    关于作用域理解的一道题
    微信站 返回上一页并刷新
    Vuex有哪些作用
    两段代码实现vue路由懒加载
    Vuex目录结构推荐
    售后打电话说现场设备出问题了,嵌入式工程师最想干什么?
    Qt编译出现cc1plus.exe: out of memory allocating 65536 bytes问题
    OpenCV计算机视觉编程攻略(第三版)源码
    C++ Json工具--Jsoncpp用法简介
  • 原文地址:https://www.cnblogs.com/tjsudys/p/4436433.html
Copyright © 2020-2023  润新知