CodeForces 540B School Marks

Description:

Little Vova studies programming in an elite school. Vova and his classmates are supposed to write n progress tests, for each test they will get a mark from 1 to p. Vova is very smart and he can write every test for any mark, but he doesn't want to stand out from the crowd too much. If the sum of his marks for all tests exceeds value x, then his classmates notice how smart he is and start distracting him asking to let them copy his homework. And if the median of his marks will be lower than y points (the definition of a median is given in the notes), then his mom will decide that he gets too many bad marks and forbid him to play computer games.

Vova has already wrote k tests and got marks a1, ..., ak. He doesn't want to get into the first or the second situation described above and now he needs to determine which marks he needs to get for the remaining tests. Help him do that.

Input:

The first line contains 5 space-separated integers: nkpx and y (1 ≤ n ≤ 999, n is odd, 0 ≤ k < n1 ≤ p ≤ 1000, n ≤ x ≤ n·p1 ≤ y ≤ p). Here n is the number of tests that Vova is planned to write, k is the number of tests he has already written, p is the maximum possible mark for a test, x is the maximum total number of points so that the classmates don't yet disturb Vova, y is the minimum median point so that mom still lets him play computer games.

The second line contains k space-separated integers: a1, ..., ak (1 ≤ ai ≤ p) — the marks that Vova got for the tests he has already written.

Output:

If Vova cannot achieve the desired result, print "-1".

Otherwise, print n - k space-separated integers — the marks that Vova should get for the remaining tests. If there are multiple possible solutions, print any of them.

Sample Input:

Input:
5 3 5 18 4
3 5 4
Output:
4 1
Input:
5 3 5 16 4
5 5 5
Output:
-1

Hint:

The median of sequence a1, ..., an where n is odd (in this problem n is always odd) is the element staying on (n + 1) / 2 position in the sorted list of ai.

In the first sample the sum of marks equals 3 + 5 + 4 + 4 + 1 = 17, what doesn't exceed 18, that means that Vova won't be disturbed by his classmates. And the median point of the sequence {1, 3, 4, 4, 5} equals to 4, that isn't less than 4, so his mom lets him play computer games.

Please note that you do not have to maximize the sum of marks or the median mark. Any of the answers: "4 2", "2 4", "5 1", "1 5", "4 1", "1 4" for the first test is correct.

In the second sample Vova got three '5' marks, so even if he gets two '1' marks, the sum of marks will be 17, that is more than the required value of 16. So, the answer to this test is "-1".

题意:Vova有n门功课需要考试,现在他已经考完了k门,并且知道自己这k门功课都分别得了多少分数,现在给出每门功课最多可得的分数p(分析之后可以发现这个p好像没啥用),我们需要算出Vova剩下的功课分别要得多少分,本来他可以都得最高分的,可是如果他的分数总和超过了x,别的同学就会抄他的作业,他是不想被打扰的,但是他也不能得分太低,要知道要是他每门功课的分数中位数如果小于y,他将不能再玩游戏了(父母要求。。)。

分析:首先我们要知道分数总和是要尽可能的小,并且中位数是要大于等于y的,那么假如n=5,11yyy应该最优的可能啦,所以我们可以知道在剩下的分数里面我们只能填写1或者y,现在关键要看填写几个1,几个y,我们可以先找到y的个数a,然后n-k-a就是1的个数啦,当然也可以先找1,这里我采取了前者。

#include<stdio.h>
#include<string.h>
#include<queue>
#include<math.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;

const int N=1e6+10;
const int INF=0x3f3f3f3f;
const int MOD=1e9+7;

typedef long long LL;

int a[N], b[N];

int main ()
{
    int n, k, p, x, y, i, flag, f, s, num, id;

    while (scanf("%d%d%d%d%d", &n, &k, &p, &x, &y) != EOF)
    {
        flag = 1; ///记录是否有满足条件的分数
        s = num = f = 0; ///s记录总分数,num记录需要添加的分数个数,f控制输出格式
        id = n; ///id记录n/2之后的分数小于y的最后位置

        for (i = 0; i < k; i++)
        {
            scanf("%d", &a[i]);
            s += a[i];
        }

        for (i = k; i < n; i++)
        {
            a[i] = 1; ///先将所有剩下的位置都填上1
            b[num++] = 1; ///b数组记录要添加的分数
            s += a[i];
        }

        if (s > x) flag = 0; ///如果剩下每门功课分数都是1,然而总分数还是>x,那么肯定没有满足条件的分数
        else
        {
            sort(a, a+n); ///先排序,找到中位数

            if (a[n/2] < y) ///如果中位数已经>=y了,那么剩下的分数直接填写1就行啦
            {
                for (i = n/2+1; i < n; i++)
                {
                    if (a[i] >= y)
                    {
                        id = i; ///找到<y的最大位置
                        break;
                    }
                }

                if (n-k < id-n/2) flag = 0; ///那么我们可以知道id-n/2是添加y的个数,但是如果剩下的个数比要添加的y的个数要少,那么没有满足条件的分数
                else
                {
                    s = s+(id-n/2)*(y-1); ///将id-n/2个已经添加的1改成y,更新总和
                    if (s > x) flag = 0; ///此时分数依然要<=x
                    else
                    {
                        for (i = 0; i < id-n/2; i++)
                            b[i] = y; ///更新b数组的值
                    }
                }
            }
        }

        if (flag == 0) printf("-1
");
        else
        {
            for (i = 0; i < num; i++)
            {
                if (f == 0) printf("%d", b[i]);
                else printf(" %d", b[i]);
                f++;
            }
            printf("
");
        }
    }

    return 0;
}
原文地址:https://www.cnblogs.com/syhandll/p/4977239.html