SOJ 1025

1025. Parallel Challenge B

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB

Description

The 2005 ACM-ICPC World Finals was held in Shanghai in April. It was a wonderful trip for Pegasus and among all the interesting activities, the IBM Parallel Challenge ballgame was the most impressive.

 The Parallel Challenge ball game gives each team a chance to pit your programming skills against those of other teams in a fast-moving parallel-programming game of skill, treachery, and hazard avoidance. Each team will write a single C++ class named MyPlayer which defines the characteristics of a “player”. The player code will be instantiated five times in the environment, making up a five-play team which will then compete in a series of Parallel Challenge ballgames running on an IBM Power Architecture Blue Gene supercomputer-the world’s fastest computer. Each of the players will run in parallel on its own separate dedicated processor in the Blue Gene.

 Each Parallel Challenge ballgame consists of a number of different teams attempting to score points while at the same time trying to hinder other teams’ ability to do so, and all the while trying also to avoid numerous hazards on the Parallel Challenge ballgame field. In each game, carrying or throwing a ball into a goal is an example of one way points can be scored.

 The objective is to write your MyPlayer class so that the players operate in a coordinated fashion, taking advantage of the various ways to score points while at the same time avoiding both hazards on the game field and impediments thrown at them by players form other teams(and, in some cases, by spectators!). The winner of a game is the team whose players score the largest total number of points.

 After the coding phase, each team must submit a final version of the MyPlayer class to the Blue Gene. The final submitted version from each team will then be run in a tournament which will take place at the Parallel Challenge Dinner in the evening. The tournament will consist of a series of rounds. Each round will consist of several Parallel Challenge ballgames between randomly chosen sets of teams. Each team’s players will participate in a least three games.

 At the end of each round teams will be ranked according to the total number of points accumulated during the games played in the round, and the top teams will advance to the next round. Each team advancing to a new round will start the new round with zero points and will be randomly regrouped with a new set of opponents. The team whose players earn the most points in the final tournament round will be the 2005 Parallel Challenge Champions.

 Now, here comes the problem:

 In the coding phase, Pegasus takes a very simple strategy to get the ball: Once the ball appears, all the players on the football field run to the position where the ball is. To simplify this problem, all the players can just run horizontally or vertically. Fig 1 shows the feasible routes of the four players. However, players lose w calories of energy while running per meter(w may be different for different players). Given the positions of all players, where should Pegasus put the ball in order to minimize the total energy loss? Assume that you can put the ball on arbitrary position as you like.

 Pegasus is stumped by this problem now. So they hope you, a distinguished programmer, to help the three poor guys to solve it.

Input

There are several test cases in the input file. The first line of each case is an integer N(1<=N<=10000), indicating the number of players on the field. N integer numbers follow, w_i, ranging from 1 to 1000 – The energy that the ith player loses while running per meter. Then there are N pairs of integers, x_i, y_i (measured in meter and 0<=x_i, y_i<=100000), indicating the coordinate of each player.
Process to the end of the file.

Output

Output the minimum total energy loss in a single line, with 2 digits after the decimal point.
Note: the minimum total energy loss means the minimum value of  by choosing the proper position (x, y) of the ball.

Sample Input

1
5
10 10
2
1 2
0 0
0 10
3
1 2 3
0 0
1 10
5 5

Sample Output

0.00
10.00
28.00

Hint

In the third example, we can put the ball in the position (1, 5).

Problem Source

ZSUACM Team Member


  题目前面一推废话,还以为要设计个机器人类什么的。这题如果穷举的话肯定是超时的,所以要想办法直接求出球的最佳坐标。方法有些类似物理学中求最小速度,一个物体达到最小速度的必要条件是加速度为0,即受力平衡。这题也是一样,要寻找平衡状态。先不考虑球的y坐标,设横坐标为x,若x左边的运动员总权重小于右边(设左边总权重w1,右边w2,w1<w2),那么向右移一格,则整体总权重则增加了w1又减少了w2,所以整体是减少的;相反若右边的总权重小于左边,那么再向右移则会使总权重增加,所以平衡位置就在左右权重相等的地方(或者左权重第一次超过右权重的地方)。对于纵坐标也类似。通过平衡态的寻找我们就能在O(n)的复杂度内求出球的最佳坐标,然后便能算出最小耗费。


// Problem#: 1025
// Submission#: 5048572
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include<iostream>
#include<iomanip>
#include<cmath>
#include<algorithm>
#include<cstdlib> 
using namespace std;
struct xy
{
    int x;//运动员横坐标 
    int y;//纵坐标 
    int w;//权重系数 
};
double minDis;//最小距离 
int N;//运动员人数 
xy player[10000];//保存运动员信息的数组 
int  posx,posy,totalW;//posx为球的横坐标,posy为纵坐标,totalw为总权重 

bool comx(xy A,xy B)
{
    return A.x<B.x;//利用sort函数按横坐标排序 
}
bool comy(xy A,xy B)
{
    return A.y<B.y;//利用sort函数按纵坐标排序 
}

void saveData()//输入数据 
{
    totalW=0; 
    for(int i=0;i<N;++i)
    {
        cin>>player[i].w;
        totalW+=player[i].w;
    }
    for(int i=0;i<N;++i)
    {
        cin>>player[i].x>>player[i].y;
    }
}
void findAnswer()
{
    sort(player,player+N,comx);//先按x排序来求出球的x坐标 
    int weight=0;//当前权重 
    for(int i=0;i<N;++i)
    {
        weight+=player[i].w;//从左至右一个一个点的往上加权重 
        if(weight>=totalW/2.0)//当当前权重第一次不小于总权重的一半时,当前点的横坐标即为posx 
        {
            posx=player[i].x;
            break;
        }
    }
    sort(player,player+N,comy);//按y排序 
    weight=0;
    for(int i=0;i<N;++i)
    {
        weight+=player[i].w;
        if(weight>=totalW/2.0)//同理当当前权重第一次不小于一半时得到posy 
        {
            posy=player[i].y;
            break;
        }
    }

}

int main()
{
    while(cin>>N)
    {
        saveData();
        findAnswer();
        minDis=0;
        for(int i=0;i<N;++i)
        {
            minDis+=(abs(posx-player[i].x)+abs(posy-player[i].y))*player[i].w;//算出了球的最佳坐标posx,posy之后只用按公式计算总耗能就行了 
        }
        cout<<fixed<<setprecision(2)<<minDis<<endl; 
    }
    return 0;
}                                 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值