• CodeForces


    题意:有n个有小写字母组成的字符串,将部分小写字母改成对应的大写字母,注意某种小写字母更改,所有的这种小写字母都会更改。若能使这给定的n个字符串符合字典序由小到大排序,则输出Yes,并输出需要修改的字母。定义所有的大写字母字典序小于小写字母。

    分析:

    1、起决定作用的是前后两个字符串中第一个不同的字母。每个字母要么小写要么大写,显然2-sat问题。

    2、假设前后两个串中第一个不同的字母分别为a,b。

    当a < b 时,只有a < B矛盾。则当a为小写时,b一定为小写。b为大写时,a一定为大写。由此建边。

    当a  > b时,a > b, A > B, a > B,都矛盾,因此,若a为小写,修改为大写,若b为大写,修改为小写。由此建边。

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<cmath>
    #include<iostream>
    #include<sstream>
    #include<iterator>
    #include<algorithm>
    #include<string>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    #include<deque>
    #include<queue>
    #include<list>
    #define lowbit(x) (x & (-x))
    const double eps = 1e-8;
    inline int dcmp(double a, double b){
        if(fabs(a - b) < eps) return 0;
        return a > b ? 1 : -1;
    }
    typedef long long LL;
    typedef unsigned long long ULL;
    const int INT_INF = 0x3f3f3f3f;
    const int INT_M_INF = 0x7f7f7f7f;
    const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
    const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f;
    const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
    const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
    const int MOD = 1e9 + 7;
    const double pi = acos(-1.0);
    const int MAXN = 100000 + 10;
    const int MAXT = 10000 + 10;
    using namespace std;
    vector<int> v[MAXN], G[MAXN << 1], rG[MAXN << 1], vs;
    bool used[MAXN << 1];
    int cmp[MAXN << 1];
    int n, m;
    vector<int> ans;
    void addedge(int from, int to){
        G[from].push_back(to);
        rG[to].push_back(from);
    }
    void dfs(int v){
        used[v] = true;
        for(int i = 0; i < G[v].size(); ++i){
            if(!used[G[v][i]]) dfs(G[v][i]);
        }
        vs.push_back(v);
    }
    void rdfs(int v, int k){
        used[v] = true;
        cmp[v] = k;
        for(int i = 0; i < rG[v].size(); ++i){
            if(!used[rG[v][i]]) rdfs(rG[v][i], k);
        }
    }
    void scc(){
        memset(used, false, sizeof used);
        vs.clear();
        for(int v = 2; v <= (m << 1 | 1); ++v){
            if(!used[v]) dfs(v);
        }
        memset(used, false, sizeof used);
        int k = 0;
        for(int i = vs.size() - 1; i >= 0; --i){
            if(!used[vs[i]]) rdfs(vs[i], k++);
        }
    }
    int main(){
        scanf("%d%d", &n, &m);
        for(int i = 0; i < n; ++i){
            int l, x;
            scanf("%d", &l);
            for(int j = 0; j < l; ++j){
                scanf("%d", &x);
                v[i].push_back(x);
            }
        }
        for(int i = 1; i < n; ++i){
            int id = -1;
            int tmp = min(v[i - 1].size(), v[i].size());
            for(int j = 0; j < tmp; ++j){
                if(v[i - 1][j] != v[i][j]){
                    id = j;
                    break;
                }
            }
            if(id == -1){
                if(v[i - 1].size() > v[i].size()){
                    printf("No
    ");
                    return 0;
                }
            }
            else if(v[i - 1][id] < v[i][id]){
                addedge(v[i - 1][id] << 1, v[i][id] << 1);
                addedge(v[i][id] << 1 | 1, v[i - 1][id] << 1 | 1);
            }
            else{
                addedge(v[i - 1][id] << 1, v[i - 1][id] << 1 | 1);
                addedge(v[i][id] << 1 | 1, v[i][id] << 1);
            }
        }
        scc();
        for(int i = 2; i <= 2 * m; ++i){
            if(cmp[i] == cmp[i + 1]){
                printf("No
    ");
                return 0;
            }
        }
        printf("Yes
    ");
        for(int i = 2; i <= 2 * m; i += 2){
            if(cmp[i] < cmp[i + 1]){
                ans.push_back(i >> 1);
            }
        }
        int len = ans.size();
        printf("%d
    ", len);
        if(len){
            for(int i = 0; i < len; ++i){
            if(i) printf(" ");
                printf("%d", ans[i]);
            }
            printf("
    ");
        }
        return 0;
    }
    

      

  • 相关阅读:
    数据结构与算法之递归与调用栈
    Linux 压缩命令之tar和zip
    算法的时间复杂度—大O表示法
    Linux三大文本处理工具之awk
    Linux 排序命令之 sort, wc, uniq
    oracle性能优化之索引
    Linux三大文本处理工具之sed命令
    Linux三大文本处理工具之grep命令
    linux查看端口
    linux查看mac地址
  • 原文地址:https://www.cnblogs.com/tyty-Somnuspoppy/p/7701400.html
Copyright © 2020-2023  润新知