zoukankan      html  css  js  c++  java
  • 2019 Multi-University Training Contest 1

    不知道错在哪里。
    是要把atop改成stop!两个弄混了。感谢自造样例。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    int n, k;
    char s[100005];
    int cnt[100005][26];
    
    deque<int> pos[26];
    
    int l[26];
    int r[26];
    int used[26];
    
    char ans[100005], atop;
    
    bool check1(int id) {
        //能不能放够下界
        //id表示剩余序列的起始位置
        int restlen = k - atop;
        int sumli = 0;
        for(int i = 0; i < 26; ++i) {
            if(cnt[id][i] < l[i] - used[i])
                return false;
            sumli += l[i] - used[i];
        }
        if(sumli > restlen)
            return false;
        //上界加起来够不够放满?
        int sumri = 0;
        for(int i = 0; i < 26; ++i) {
            sumri += r[i] - used[i];
        }
        if(sumri < restlen)
            return false;
        return true;
    }
    
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
    #endif // Yinku
        while(~scanf("%s%d", s + 1, &k)) {
            for(int i = 0; i < 26; ++i) {
                pos[i].clear();
                used[i] = 0;
            }
            n = strlen(s + 1);
            for(int i = 1; i <= n; ++i) {
                pos[s[i] - 'a'].push_back(i);
                for(int j = 0; j < 26; ++j) {
                    cnt[i][j] = 0;
                }
                ++cnt[i][s[i] - 'a'];
            }
            for(int i = n - 1; i >= 1; --i) {
                for(int j = 0; j < 26; ++j) {
                    cnt[i][j] += cnt[i + 1][j];
                }
            }
            for(int i = 0; i < 26; ++i) {
                scanf("%d%d", &l[i], &r[i]);
            }
            atop = 0;
            bool suc2 = true;
            while(atop < k) {
                ++atop;
                //给第1个位置选
                bool suc = false;
                for(int i = 0; i < 26; i++) {
                    while(pos[i].size() && pos[i].front() < atop)
                        pos[i].pop_front();
    
                    if(used[i] < r[i] && pos[i].size()) {
                        used[i]++;
                        if(check1(pos[i].front() + 1)) {
                            suc = true;
                            ans[atop] = 'a' + i;
                            ans[atop + 1] = '';
                            pos[i].pop_front();
                            break;
                        }
                        used[i]--;
                    }
                }
                if(!suc) {
                    suc2 = false;
                    break;
                }
            }
            if(suc2)
                printf("%s
    ", ans + 1);
            else
                puts("-1");
        }
    }
    

    有一个可以导致出错的样例:

    abcdeabcdeabcdeabcdeabcdeabcde 14
    0 3
    2 3
    3 5
    3 5
    3 7
    0 0
    0 0
    0 0
    0 0
    0 0
    0 0
    0 0
    0 0
    0 0
    0 0
    0 0
    0 0
    0 0
    0 0
    0 0
    0 0
    0 0
    0 0
    0 0
    0 0
    0 0
    

    目前通过的代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    int n, k;
    char s[100005];
    int cnt[100005][26];
    
    deque<int> pos[26];
    
    int l[26], r[26], used[26];
    
    char ans[100005];
    
    int atop, stop;
    
    bool check1(int id) {
        //能不能放够下界
        //id表示剩余序列的起始位置
        int restlen = k - atop;
        int sumli = 0;
        for(int i = 0; i < 26; ++i) {
            if(cnt[id][i] < l[i] - used[i])
                return false;
            sumli += max(l[i] - used[i], 0);
        }
        if(sumli > restlen)
            return false;
        //上界加起来够不够放满?
        int sumri = 0;
        for(int i = 0; i < 26; ++i) {
            sumri += min(r[i] - used[i], cnt[id][i]);
        }
        if(sumri < restlen)
            return false;
        return true;
    }
    
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
    #endif // Yinku
        while(~scanf("%s%d", s + 1, &k)) {
            memset(used, 0, sizeof(used));
            n = strlen(s + 1);
            for(int i = 0; i < 26; ++i) {
                pos[i].clear();
                used[i] = 0;
                cnt[n + 1][i] = 0;
            }
            for(int i = 1; i <= n; ++i) {
                pos[s[i] - 'a'].push_back(i);
                for(int j = 0; j < 26; ++j) {
                    cnt[i][j] = 0;
                }
                ++cnt[i][s[i] - 'a'];
            }
    
            for(int i = n - 1; i >= 1; --i)
                for(int j = 0; j < 26; ++j)
                    cnt[i][j] += cnt[i + 1][j];
            for(int i = 0; i < 26; ++i)
                scanf("%d%d", &l[i], &r[i]);
    
            atop = 0;
            stop = 0;
            bool suc2 = true;
            while(atop < k) {
                ++atop;
                //给第1个位置选
                bool suc = false;
                for(int i = 0; i < 26; i++) {
                    while(pos[i].size() && pos[i].front() <= stop)
                        pos[i].pop_front();
    
                    if(used[i] < r[i] && pos[i].size()) {
                        used[i]++;
                        if(check1(pos[i].front() + 1)) {
                            suc = true;
                            ans[atop] = 'a' + i;
                            ans[atop + 1] = '';
                            stop = pos[i].front();
                            pos[i].pop_front();
                            break;
                        }
                        used[i]--;
                    }
                }
                if(!suc) {
                    suc2 = false;
                    break;
                }
            }
            ans[k + 1] = '';
            if(suc2)
                printf("%s
    ", ans + 1);
            else
                puts("-1");
        }
    }
    
  • 相关阅读:
    一道小学数学题
    Ubuntu下使用git提交代码至GitHub
    C#几个小知识点
    C#中巧用#if DEBUG 进行调试
    使用 HPC Pack 为 Azure 中的 Windows HPC 工作负荷创建和管理群集的选项
    使用 Chef 自动执行 Azure 虚拟机部署
    在 Azure 中管理 Windows 虚拟机的可用性
    什么是 Azure 中的虚拟机规模集?
    从 Azure 下载 Windows VHD
    如何使用 Packer 在 Azure 中创建 Windows 虚拟机映像
  • 原文地址:https://www.cnblogs.com/Yinku/p/11231505.html
Copyright © 2011-2022 走看看