Fair Division

Description

It’s your friend’s birthday, and you and some other people decided to buy him a copy of StarCraft II,because who wouldn’t want to have that ?

You agreed to divide the costs as fairly as possible. Since some of you have more money availablethan others, you also agreed that nobody has to pay more than he can afford. Every contribution will be a multiple of 1 cent, i.e., nobody can pay fractions of a cent.

Everybody writes down the maximum amount he is able to contribute. Taking into account these maximum amounts from everybody, you share the cost of the present as fairly as possible. That means,you minimize the largest distance of the contributions to (1/n)th of the total cost. In case of a tie, minimize the second largest distance, and so on. 

Since the smallest unit of contribution is 1 cent, there might be more than one possible division of the cost. In that case,persons with a higher maximum amount pay more. If there is still ambiguity, those who come first in the list pay more.Since you bought the present, it is your task to figure out how much everybody has to pay (including you).

Input

On the first line a positive integer: the number of test cases, at most 100. After that per test case:

• One line with two integers p and n: the price of the present in cents (1 ≤ p ≤ 1 000 000) and the number of people (2 ≤ n ≤   100) who contribute to the present (including you).

• One line with n integers ai (1 ≤ ai ≤ 1 000 000), where ai is the maximum amount, in cents,that the i-th person on the list is able to contribute.

Output

Per test case:

• One line with n integers: the amounts each person has to contribute according to the scheme. If the total cost can not be divided according to the above rules, the line must contain ‘IMPOSSIBLE’ instead.

Sample Input

3

20 4

10 10 4 4

3

1 1 4

34 5

9 8 9 9 4

Sample Output

6 6 4 4

IMPOSSIBLE

8 7 8 7 4

题意:几个人一起买一件礼物,花费sum,已知每个人所能分担的最大费用,现在要求分配每个人实际承担的费用,使得:价格之间尽量接近(尽量平均,题目说的那么费劲实             际上就是这个意思!!),如果在这个要求下有多组解决方案,则可分担额度最大的人多出,如果解决方案仍不唯一,则在输入次序中排序靠前的,多出。求解决方案,             即每个人实际担负的费用

分析:尽量平均,这个思路很好想的其实。。感觉比赛的时候就是被题目的说法绕进去了。。不然怎么也不可能连这个想法都想不到:既然让尽量平均,我们就先求平均值sum/n  n为人数,这个时候,我们根据多组解时“可分担额度最大的人多出,如果解决方案仍不唯一,则在输入次序中排序靠前的,多出”的处理原则,对输入数据以最大额度为第一关键字,输入次序index为次要关键字 进行双关键字排序。

           然后就是对每一个人,考虑他能负担的最大额度和平均值之间的关系,需要注意的是,平均值并不是一成不变的sum/n,每决定一个人支付的费用,剩余需要支付的费用都会减少,平均值也会随之变化。

           如果当下的平均值大于这个人的负担额度,那么他只用出负担额度就够了,这就是子最优解。

           如果小于,那么就出当前平均值

          最后,按照输入次序从新排序,输出每个人的实际出价即可

code:

#include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#define maxn 100010
using namespace std;

int t;
int num;
int sum;

int p[110];
struct node
{
    int value,index,con;
}q[110];
bool cmp1(node a,node b)
{
    if(a.value!=b.value){
    return a.value<b.value;
    }
    return a.index>b.index;
}
bool cmp2(node a,node b)
{
    return a.index<b.index;
}
int main()
{
    cin>>t;
    while(t--)
    {
        int s=0;
        cin>>sum>>num;
        for(int i=0;i<num;i++)
        {
            scanf("%d",&q[i].value);
            q[i].index=i;
            s+=q[i].value;
        }
        if(s<sum)
        {
            printf("IMPOSSIBLE\n");
            continue;
        }
        sort(q,q+num,cmp1);
        for(int i=0;i<num;i++)
        {
            q[i].con=min(q[i].value,sum/(num-i));
            sum-=q[i].con;
        }
        sort(q,q+num,cmp2);
        for(int i=0;i<num;i++)
        {
            if(i<num-1)
            {
                printf("%d ",q[i].con);
            }
            else
            {
                printf("%d\n",q[i].con);
            }
        }
    }
}
P.S.   今天的组队赛第一场,表现太烂了,整个人不在状态。这样的情况让我很不爽。。

          哪怕现在我是个菜,也得发挥出菜的最高水平!

          或许我的确需要被刺激一下,才能逼迫出潜能吧。。

          I  WILL BE BETTER

          I CAN BE THE BEST


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值