codeforces 875C - National Property

http://codeforces.com/contest/875/problem/C

题意:给你 n 个字符串,每个字符串的字符为 1 到 m,可以使所有字符串中某个相同字符变成大写字符,如 1 -> 1'。定义所有大写字符均小于小写字符, 如:2 < 3, 2' < 3', 3' < 2,让你求是否可以转变某些字符,是 n 个字符串字典序升序排序。

题解:大暴力过去。dfs(int l, int r, int id) 表示字符串 [ l , r ] 的前 id 个字符完全相同,现在从第 id+1个字符开始算,也就是只有看第 di+1列字符是否升序排序就好,由于第 id+1 列的字符变成大写  会影响到  id 前的列数,所以这次做完再次dfs就行。

#include<cstdio>
#include<string>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<set>
#define oo 0x3f3f3f3f
#define mod 1000000007
using namespace std;
const int MAXN = 100000+10;
const int MAXM = 100000+10;
int a[MAXM];
bool cg[MAXN];
vector<int> ve[MAXN];
int fact(int id)
{
    if(cg[id]) return a[id]-100000;
    return a[id];
}
bool ans, ok;
void dfs(int l, int r, int id)
{
    if( !ans ) return ;
    if(l >= r) return ;
    while(l <= r && id >= ve[l].size() ) l++;
    for(int i = l+1; i <= r; ++i)
    {
        if(id >= ve[i].size())
        {
            ans = false;
            return ;
        }
        if( fact(ve[i][id]) < fact(ve[i-1][id]) )
        {
            for(int j = i-1; j >= l; --j)
            {
                if( fact(ve[j+1][id]) > fact(ve[j][id]) )
                {
                    break;
                }
                if( !cg[ ve[j][id] ] )
                {
                    ok = true;
                }
                cg[ ve[j][id] ] = true;
                if( fact(ve[j+1][id]) < fact(ve[j][id]) )
                {
                    ans = false;
                    return ;
                }
            }
        }
    }
    int kk = l;
    for(int i = l; i <= r; ++i)
    {
        if(ve[i][id]!=ve[kk][id])
        {
            dfs(kk, i-1, id+1);
            if(!ans) return ;
            kk = i;
        }
        if(i==r&&ve[i][id]==ve[kk][id])
        {
            dfs(kk, i, id+1);
            if(!ans) return ;
        }
    }
}
int main (void)
{
    ios::sync_with_stdio(false);
    int n, m; cin >> n >> m; 
    memset(cg, false, sizeof(cg));
    for(int i = 1; i <= m; ++i)
    {
        a[i] = i;
    }
    for(int i = 1; i <= n; ++i)
    {
        int l; cin >> l;
        for(int j = 1; j <= l; j++)
        {
            int x; cin >> x;
            ve[i].push_back(x);
        }
    }
    ans = true;
    ok = true;
    while(ok && ans)
    {
        ok = false;
        dfs(1, n, 0);
    }
    dfs(1, n, 0);
    if(!ans)
    {
        cout << "No";
        return 0;
    }
    int sum = 0;
    for(int i = 1; i <= m; ++i)
    {
        if(cg[i]) ++sum;
    }
    cout << "Yes" << endl;
    cout << sum << endl;
    for(int i = 1; i <= m; ++i)
    {
        if(cg[i]) cout<<i<<' ';
    }
}

 

posted @ 2017-10-17 21:42  黑.白  阅读(629)  评论(0编辑  收藏  举报