codeforces1009G Allowed Letters [greedy] + hall Theorem

Because it is so greedy selected current lexicographical can choose the minimum, so the question is how to quickly calculate the current position can not choose an enumeration of the letter
sequence after rearrangement of the original sequence and is a perfect match, and the need to meet the perfect match hall theorem, i.e. on the left of any set of k constant and at least k points to the right are connected
and a total of six characters, the original sequence of the same character point even the set of points is the same, so long as the 2 ^ 6 set of characters satisfy hall Theorem each time so you can determine what the enumeration-like pressure

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=100005;
int n,m,sm[N],f[N][70],ok[N];
char s[N],c[10],flg,ans[N];
int main()
{
    scanf("%s%d",s+1,&m);
    n=strlen(s+1);
    for(int i=1;i<=n;i++)
        for(int j=0;j<(1<<6);j++)
            if(j&(1<<(s[i]-'a')))
                sm[j]++;
    for(int i=1;i<=n;i++)
        ok[i]=(1<<6)-1;
    for(int i=1,x;i<=m;i++)
    {
        scanf("%d%s",&x,c+1);
        ok[x]=0;
        for(int j=1;j<=strlen(c+1);j++)
            ok[x]+=(1<<(c[j]-'a'));
    }
    for(int i=n;i>=1;i--)
        for(int j=0;j<(1<<6);j++)
            f[i][j]=f[i+1][j]+(((j&ok[i])==ok[i])?1:0);
    for(int i=1;i<=n;i++)
    {
        bool fl=0;
        for(int j=0;j<6&&!fl;j++)
            if(sm[1<<j]&&(ok[i]&(1<<j)))
            {
                flg=1;
                for(int k=0;k<(1<<6)&&flg;k++)
                    if(f[i+1][k]>sm[k]-((k>>j)&1))
                        flg=0;
                if(flg)
                {
                    fl=1;
                    ans[i]='a'+j;
                    for(int k=0;k<(1<<6);k++)
                        if(k&(1<<j))
                            sm[k]--;
                }
            }
        if(!flg)
        {
            puts("Impossible");
            return 0;
        }
    }
    for(int i=1;i<=n;i++)
        printf("%c",ans[i]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/lokiii/p/10959864.html