zoukankan      html  css  js  c++  java
  • UVa 11491

    题意

    给出一个长度为n的数字串, 要求删去d个数字, 使得剩下的总数字最大 (1 ≤ d < n ≤ 10^5 )

    思路

    根据贪心策略, 越高位的数字越大越好.
    但取高位数字时同时要保证剩余量能够满足一共选出n-d个数字
    考虑到用优先队列
    但同时要记录下刚才取出的数字所在位置, 每次把队列中位置在上次选出数字所在位置之前的元素弹出

    AC代码

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <map>
    #define mst(a) memset(a, 0, sizeof(a))
    
    using namespace std;
    
    const int maxn = 1e5+10;
    
    struct Node
    {
        int v, pos;
        bool operator < (const Node& node) const {   //定义优先队列的排序方式
            return v < node.v || (v == node.v && pos > node.pos);
        }
    }p[maxn];
    
    string s;
    priority_queue<Node> que;
    int a, b, c, mrk;  //mrk用于记录目前出队卡到第几位
    
    void init(){
        while( que.size() ){ que.pop(); }
        mrk = 0;
        s = "";
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        while( cin >> a >> b && a )
        {
            init();
            string ss = "";
            b = a - b; //b定义改为剩余多少数字
            cin >> s;
            for( int i = 0; i < a; i++ ){
                p[i].v = s[i] - '0';
                p[i].pos = i;
                if( i <= a - b )  que.push(p[i]);
            }
            int mrk = -1;
            int i = a - b;
            //cout << "size:" << que.size() << endl;
            while( b ){
                while( que.top().pos < mrk )    que.pop();
                //cout << que.top().v << endl;
                char tmp = que.top().v + '0';
                ss += tmp;
                mrk = que.top().pos;
                que.pop();
                if( i < a )  que.push(p[++i]);
                b--;
            }
            cout << ss << endl;
        }
        return 0;
    }
    

    TLE代码 ( 一开始没考虑到时间复杂度的超时代码 )

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <map>
    #define mst(a) memset(a, 0, sizeof(a))
    
    using namespace std;
    
    const int maxn = 1e5+10;
    string s;
    typedef priority_queue<int> Q;
    int a, b, c, mrk;  //mrk用于记录目前出队卡到第几位
    
    void init(){
        //if( que.size() ){ que.empty(); }
        mrk = 0;
        s = "";
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        while( cin >> a >> b && a )
        {
            init();
            string ss = "";
            b = a - b; //b定义改为剩余多少数字
            cin >> s;
            int len = s.size();
            while( b-- ){
                Q que;
                int tmp;
                map<int, int> mp;
                //cout << mrk << ' ' << len-b << endl;
                for( int i = mrk; i < len - b && i < len; i++ ){
                    tmp = s[i] - '0';
                    que.push(tmp);
                    if( !mp.count(tmp) )  mp.insert( make_pair(tmp, i) );
                }
                char a = que.top() + '0';
                ss += a;
                mrk = mp[que.top()]+1;
            }
            cout << ss << endl;
        }
        return 0;
    }
  • 相关阅读:
    Linux下如何查看哪些进程占用的CPU内存资源最多
    linux查看端口占用情况
    oracle11g用户名密码不区分大小写
    oracle表导入导出
    Oracle的实例占用内存调整
    修改oracle内存
    ORA-04031: 无法分配 共享内存
    OCI_INVALID_HANDLE 什么原因
    Android SDK Manager国内无法更新的解决方案
    sqlite3增删改查简单封装
  • 原文地址:https://www.cnblogs.com/JinxiSui/p/9740574.html
Copyright © 2011-2022 走看看