• 【CJOJ P2110】YL杯超级篮球赛


    【CJOJ P2110】YL杯超级篮球赛

    Description

    一年一度的高一YL杯超级篮球赛开赛了。当然,所谓超级的意思是参赛人数可能多于5人。小三对这场篮球赛非常感兴趣,所以一场都没有落下。每天中午都准时守候在篮球场看比赛。经过一个星期的研究,小三终于对篮球的技战术找到了一丝丝感觉。他发现打YL杯的每个班都有一套相似的进攻战术:
    1.控球后卫带球到前场,找到一个最佳攻击点(x,y)。
    2.所有除控卫以外的队员都从各自的当前位置迅速向(x,y)移动。
    3.控球后卫根据场上情况组织进攻。
    这个战术对于一般情况是非常奏效的,但是每个队员毕竟不像小三一样每天精力过剩,每个队员都有一个疲劳指数w,显然对于每个队员的移动需要消耗一些能量。
    假设一个队员从位置xl,y1)移动到(x,y)的能量消耗为w*(ABS(x-x1)+ABS(y-y1)),这里ABS为绝对值函数,那么我们希望整个队伍一次进攻的能量消耗当然是越少越好。显然能量消耗的多少直接取决于控球后卫对于攻击点(x,y)的选择。
    因为参赛人数众多,所以小三希望你能编写一个程序,帮他找出某个时刻的最佳攻击点。

    Input

    第一行:一个整数N,表示篮球队人数
    第二行:一共N个整数,其中的第i个数Wi表示第i个队员的疲劳指数。
    第3~N+2行:每一行两个整数x和Y,表示其中的第i+2行,表示第i个队员的当前位置的横坐标和纵坐标。

    Output

    一个实数。表示所有队员集合到最佳攻击位置的能量消耗总和,答案保留两位小数。

    样例输入

    1
    1
    0 0

    样例输出

    0.00

    数据规模

    n<=50000
    0<w<=1000
    0<x,y<=1000000

    题解

    这道题有点像士兵站队问题,每一个人的疲劳值直接看成重复的几个人即可。可以自己试着画一下,发现会很简单。把每个人的横坐标、纵坐标全部排序,然后依次就中位数计算就可以了,具体的证明请自己温习初一的绝对值距离。这道题的写法很好的利用到了中位数/绝对值的使用。

    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath> 
    #include<algorithm>
    using namespace std;
    int w[50001],n;
    long long sum=0;
    struct dsl
    {
    	    int a;
    	    int w;
    };//结构体定义
     
    bool cmp(dsl k,dsl d)
    {
    	    return k.a<d.a;
    }//比较函数(方便直接调用sort)
    dsl x[50001],y[50001];
     
    int main()
    {
    	               //读入 
    		    long long cd=0;
        	    cin>>n;
        	    for(int i=1;i<=n;++i)
        	    {
        	          scanf("%d",&w[i]);
        	          x[i].w=w[i];
    		          y[i].w=w[i];
        	          cd+=w[i];
                }            
        	    for(int i=1;i<=n;++i)
        	          scanf("%d%d",&x[i].a,&y[i].a);
                        
                           //排序 
                 sort(&x[1],&x[n+1],cmp);
                 sort(&y[1],&y[n+1],cmp); 
            		       //计算 
                int k;
                cd=int(((cd+1)/2)+0.5);
                long long g=cd;
                for(int i=1;i<=n;++i)
                 {
             	        cd-=x[i].w;
             	        if(cd<=0){k=i;break;}
    		     }
                for(int i=1;i<=n;++i)
                     sum+=abs(x[k].a-x[i].a)*x[i].w;
             
             
                cd=g;
                for(int i=1;i<=n;++i)
                 {
             	        cd-=y[i].w;
             	        if(cd<=0){k=i;break;}
    		     }
    	        for(int i=1;i<=n;++i)
    	             sum+=abs(y[k].a-y[i].a)*y[i].w;
    	                    //利用绝对值进行计算
    	     
    	     		       //输出	
    	        cout<<sum<<".00"<<endl;
    	                   //由绝对值的最小值和题目数据可知,结果一定是一个整数
    	                   //但是要求输出的事小数点后两位,所以直接打印".00"
        	    return 0;
    }
    
  • 相关阅读:
    二分查找,你真的学会了吗
    解决Devexpress的RichEditControl控件保存为docx文件后在word里打开字体显示不正确的问题
    protocgengo: unable to determine Go import path for "xxx.proto"
    URL 和 URI 区别
    Ubuntu 强制关闭图形窗口
    centos /lib64/libc.so.6: version `GLIBC_2.28' not found (required by
    Mac OS 修改终端 Terminal 的配色
    Go语言 http 中的 request.Host 和 request.URL.Host 的区别
    Go 中 defer 和 return 执行的先后顺序
    NPOI 将DataSet保存成Excel文件
  • 原文地址:https://www.cnblogs.com/cjyyb/p/7196603.html
Copyright © 2020-2023  润新知