zoukankan      html  css  js  c++  java
  • Codeforces F. Maxim and Array(构造贪心)

    题目描述:

    Maxim and Array

    time limit per test

    2 seconds

    memory limit per test

    256 megabytes

    input

    standard input

    output

    standard output

    Recently Maxim has found an array of n integers, needed by no one. He immediately come up with idea of changing it: he invented positive integer x and decided to add or subtract it from arbitrary array elements. Formally, by applying single operation Maxim chooses integer i (1 ≤ i ≤ n) and replaces the i-th element of array a**i either with a**i + x or with a**i - x. Please note that the operation may be applied more than once to the same position.

    Maxim is a curious minimalis, thus he wants to know what is the minimum value that the product of all array elements (i.e. img) can reach, if Maxim would apply no more than k operations to it. Please help him in that.

    Input

    The first line of the input contains three integers n, k and x (1 ≤ n, k ≤ 200 000, 1 ≤ x ≤ 109) — the number of elements in the array, the maximum number of operations and the number invented by Maxim, respectively.

    The second line contains n integers a1, a2, ..., a**n (img) — the elements of the array found by Maxim.

    Output

    Print n integers b1, b2, ..., b**n in the only line — the array elements after applying no more than k operations to the array. In particular, img should stay true for every 1 ≤ i ≤ n, but the product of all array elements should be minimum possible.

    If there are multiple answers, print any of them.

    Examples

    Input

    Copy

    5 3 1
    5 4 3 5 2
    

    Output

    Copy

    5 4 3 5 -1 
    

    Input

    Copy

    5 3 1
    5 4 3 5 5
    

    Output

    Copy

    5 4 0 5 5 
    

    Input

    Copy

    5 3 1
    5 4 4 5 5
    

    Output

    Copy

    5 1 4 5 5 
    

    Input

    Copy

    3 2 7
    5 4 2
    

    Output

    Copy

    5 11 -5 
    

    思路:

    题目是要求给一个数列,k次操作在某个数上加或减x,让数列乘积最小。因为数有正负,要分情况讨论。

    如果现在负数个数是偶数,就是乘积是个正数,应该相办法让它变成负,就让绝对值最小的变,因为它距离零最近。如果要变的是正数,就减x,如果是负数要变,就加x,即使不能让乘积编号也可以让乘积变小。

    如果现在负数个数是奇数,乘积是个负数,我们要让乘积的绝对值更大来使乘积更小。就变绝对值最小的,是正数就加x,是负数就减x,因为当一堆数大小越接近,这堆数的乘积越大。

    注意每次变化要更新负数的个数,要快速取得绝对值最小的元素,要维护一个结构体的优先级队列,需要在结构体的定义里重载<运算符。

    刚开始我沙雕用了两个队列,一个存整数,一个存负数,每次选绝对值小的还要比较,(if-else)写了一大堆最后还错了。-_-||详见后面的代码。

    代码:

    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #define max_n 200005
    using namespace std;
    int n,k,x;
    long long a[max_n];
    struct node
    {
        int id;
        long long val;
        bool operator<(const node& a) const
        {
            return abs(val-0)>abs(a.val-0);
        }
    };
    int cnt = 0;
    priority_queue<node> que;
    int main()
    {
        cin >> n >> k >> x;
        for(int i = 0;i<n;i++)
        {
            cin >> a[i];
            node nw;
            nw.val = a[i];
            nw.id = i;
            if(a[i]<0)
            {
                cnt++;
            }
            que.push(nw);
        }
        while(k)
        {
            node nw = que.top();
            int id = nw.id;
            if(cnt%2==0)
            {
                if(a[id]<0)
                {
                    a[id] += x;
                    if(a[id]>=0)
                    {
                        cnt--;
                    }
                }
                else
                {
                    a[id] -= x;
                    if(a[id]<0)
                    {
                        cnt++;
                    }
                }
            }
            else
            {
                if(a[id]<0)
                {
                    a[id] -= x;
                }
                else
                {
                    a[id] += x;
                }
            }
            nw.val = a[id];
            que.pop();
            que.push(nw);
            k--;
        }
        for(int i = 0;i<n;i++)
        {
            cout << a[i] << " ";
        }
        cout << endl;
    }
    
    

    不明哪里写错的代码:

    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #define max_n 200005
    using namespace std;
    long long n,k,x;
    long long a[max_n];
    struct node
    {
        int id;
        long long val;
        bool operator<(const node& a) const
        {
            return abs(val-0)>abs(a.val-0);
        }
    };
    priority_queue<node> fque;
    priority_queue<node> zque;
    int main()
    {
        cin >> n >> k >> x;
        for(int i = 0;i<n;i++)
        {
            cin >> a[i];
            node nw;
            nw.val = a[i];
            nw.id = i;
            if(a[i]<0)
            {
    
                fque.push(nw);
            }
            else
            {
                zque.push(nw);
            }
        }
        //cout << "input " << endl;
        while(k)
        {
            /*for(int i = 0;i<n;i++)
            {
                cout << a[i] << " ";
            }
            cout << endl;*/
            if(fque.size()%2==0)
            {
                if(fque.size()==0)
                {
                    int id = zque.top().id;
                    a[id] -= x;
                    node nw;
                    nw.id = id;
                    nw.val = a[id];
                    if(a[id]<0)
                    {
                        zque.pop();
                        fque.push(nw);
                    }
                    else
                    {
                        zque.pop();
                        zque.push(nw);
                    }
                }
                else if(zque.size()==0)
                {
                    int id = fque.top().id;
                    a[id] += x;
                    node nw;
                    nw.id = id;
                    nw.val = a[id];
                    if(a[id]>=0)
                    {
                        fque.pop();
                        zque.push(nw);
                    }
                    else
                    {
                        fque.pop();
                        fque.push(nw);
                    }
                }
                else
                {
                    int gapz = abs(zque.top().val-0);
                    int idz = zque.top().id;
                    int gapf = abs(fque.top().val-0);
                    int idf = fque.top().id;
                    if(gapz<gapf)
                    {
                        a[idz] -= x;
                        node nw;
                        nw.id = idz;
                        nw.val = a[idz];
                        if(a[idz]<0)
                        {
                            zque.pop();
                            fque.push(nw);
                        }
                        else
                        {
                            zque.pop();
                            zque.push(nw);
                        }
                    }
                    else
                    {
                        a[idf] += x;
                        node nw;
                        nw.id = idf;
                        nw.val = a[idf];
                        if(a[idf]>=0)
                        {
                            fque.pop();
                            zque.push(nw);
                        }
                        else
                        {
                            fque.pop();
                            fque.push(nw);
                        }
                    }
                }
            }
            else
            {
                if(zque.size()==0)
                {
                    int id = fque.top().id;
                    a[id] -= x;
                    node nw;
                    nw.id = id;
                    nw.val = a[id];
                    fque.pop();
                    fque.push(nw);
                }
                else
                {
                    int gapz = abs(zque.top().val-0);
                    int idz = zque.top().id;
                    int gapf = abs(fque.top().val-0);
                    int idf = fque.top().id;
                    if(gapz<gapf)
                    {
                        a[idz] += x;
                        zque.pop();
                        node nw;
                        nw.id = idz;
                        nw.val = a[idz];
                        zque.push(nw);
                    }
                    else
                    {
                        a[idf] -= x;
                        fque.pop();
                        node nw;
                        nw.id = idf;
                        nw.val = a[idf];
                        fque.push(nw);
                    }
                }
            }
            k--;
        }
        for(int i = 0;i<n;i++)
        {
            cout << a[i] << " ";
        }
        cout << endl;
        return 0;
    
    }
    
    

    参考文章:

    木流牛马,D. Maxim and Array,https://www.cnblogs.com/thunder-110/p/9340279.html

  • 相关阅读:
    oracle 创建视图、修改视图、删除视图、利用视图操作基本表
    FileZilla Server的安装和设置
    js网站
    图解局域网共享设置步骤
    PLSQL连接ORACLE详解
    PLSQL Developer图形化窗口创建数据库全过程
    60多个精品源码站
    日历控件
    LINQ 101例子
    SharpZipLib压缩打包多个文件
  • 原文地址:https://www.cnblogs.com/zhanhonhao/p/11365873.html
Copyright © 2011-2022 走看看