「NOI2017」問題解決のゲームレポート

「NOI2017」ゲーム

\(Dの\は)あなたが直接検討するほど小さい(D \)\暴力的な何か

列挙\(X \)される(\)\または\(B \)(\ (Cの\)希望しない、なぜなら\(B \)が既に含まれている\(Cを\) )、および残りです\(2-土\)の問題は、

しかし、あなたはケースがあることがわかり、場合\(\)される(B \)を\場合は、\(B \)がされる(禁止\)を\、その後、\(\)がなければなりません(禁止を\ \ )

私たちは、それが記録(禁止\)\のポイント、プログラムは(ソートトポを使用していたときにボールを見てみ宣告します..

しかし、実際にある\(A \)でも、\(\ LNOT A \) SCCの、あなたが直接比較できる大きさに従事する番号計画


コード:

#include <cstdio>
#include <cctype>
#include <cstring>
#include <vector>
#include <algorithm>
using std::min;
const int SIZE=1<<21;
char ibuf[SIZE],*iS,*iT;
//#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),iS==iT?EOF:*iS++):*iS++)
#define gc() getchar()
template <class T>
void read(T &x)
{
    x=0;char c=gc();
    while(!isdigit(c)) c=gc();
    while(isdigit(c)) x=x*10+c-'0',c=gc();
}
template <class T>
void reads(T &x)
{
    char c=gc();
    while(c<'a'||c>'z') c=gc();
    x=c-'a'+1;
}
template <class T>
void readb(T &x)
{
    char c=gc();
    while(c<'A'||c>'Z') c=gc();
    x=c-'A'+1;
}
const int N=2e5+10;
int head[N],to[N],Next[N],cnt;
void add(int u,int v)
{
    to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt;
}
struct _toki
{
    int a,b,c,d;
}toki[N];
int n,m,_n,yuu[N][4],ops[N],saki[N];
int val[N],ban[N],Ban[N],q[N],bel[N],opsi[N];
int low[N],dfn[N],in[N],sta[N],tot,dfsclock;
std::vector <int> E[N];
void tarjan(int now)
{
    dfn[now]=low[now]=++dfsclock;
    in[sta[++tot]=now]=1;
    for(int v,i=head[now];i;i=Next[i])
    {
        if(!dfn[v=to[i]])
        {
            tarjan(v);
            low[now]=min(low[now],low[v]);
        }
        else if(in[v])
            low[now]=min(low[now],dfn[v]);
    }
    if(low[now]==dfn[now])
    {
        int k;++_n;
        do
        {
            k=sta[tot--];
            in[k]=0;
            bel[k]=_n;
        }while(now!=k);
    }
}
int solve()
{
    memset(head,0,sizeof head);cnt=0;
    memset(ban,0,sizeof ban);
    memset(Ban,0,sizeof Ban);
    for(int a,b,c,d,i=1;i<=m;i++)
    {
        a=toki[i].a,b=toki[i].b,c=toki[i].c,d=toki[i].d;
        if(saki[a]==b) continue;
        if(saki[c]==d)
        {
            ban[yuu[a][b]]=1;
            continue;
        }
        add(yuu[a][b],yuu[c][d]);
        add(ops[yuu[c][d]],ops[yuu[a][b]]);
    }
    memset(in,0,sizeof in);
    memset(dfn,0,sizeof dfn);
    memset(low,0,sizeof low);
    memset(bel,0,sizeof bel);
    memset(opsi,0,sizeof opsi);
    _n=dfsclock=0;
    for(int i=1;i<=n<<1;i++)
        if(!dfn[i])
            tarjan(i);
    for(int i=1;i<=n;i++)
        if(bel[i]==bel[i+n])
            return -1;
    memset(val,-1,sizeof val);
    for(int i=1;i<=_n;i++) E[i].clear();
    //int ecnt=0;
    for(int u=1;u<=n<<1;u++)
    {
        for(int v,i=head[u];i;i=Next[i])
            if(bel[u]!=bel[v=to[i]])
                E[bel[v]].push_back(bel[u]),++in[bel[u]];//++ecnt;
        Ban[bel[u]]|=ban[u];
        opsi[bel[u]]=bel[ops[u]];
    }
    int l=1,r=0;
    for(int i=1;i<=_n;i++)
        if(!in[i]&&!Ban[i])
            q[++r]=i;
    while(l<=r)
    {
        int now=q[l++];
        if(val[now]==-1) val[now]=0,val[opsi[now]]=1;
        for(int v,i=0;i<E[now].size();i++)
        {
            v=E[now][i];
            --in[v];
            if(!in[v]&&!Ban[v]) q[++r]=v;
        }
    }
    for(int i=1;i<=n;i++)
        if(val[bel[i]]==-1)
            return -1;
    for(int i=1;i<=n;i++)
    {
        int x=val[bel[i]];
        for(int j=1;j<=3;j++)
        {
            if(saki[i]!=j)
            {
                if(!x) putchar('A'+j-1);
                --x;
            }
        }
        //puts("");
    }
    return 0;
}
int main()
{
    //freopen("game.in","r",stdin);
    //freopen("game.out","w",stdout);
    int d,yuy[10];
    read(n),read(d);
    d=0;
    for(int i=1;i<=n;i++)
    {
        ops[i]=i+n;
        ops[i+n]=i;
        reads(saki[i]);
        if(saki[i]==24)
        {
            yuy[++d]=i;
            continue;
        }
        int aya=i;
        for(int j=1;j<=3;j++)
        {
            if(saki[i]!=j)
            {
                yuu[i][j]=aya;
                aya+=n;
            }
        }
    }
    read(m);
    for(int i=1;i<=m;i++) read(toki[i].a),readb(toki[i].b),read(toki[i].c),readb(toki[i].d);
    if(!d)
    {
        if(solve()==-1) puts("-1");
        return 0;
    }
    for(int s=0;s<1<<d;s++)
    {
        for(int i=1;i<=d;i++)
        {
            if(!(s>>i-1&1))
            {
                saki[yuy[i]]=1;
                yuu[yuy[i]][2]=yuy[i];
                yuu[yuy[i]][3]=yuy[i]+n;
            }
            else
            {
                yuu[yuy[i]][1]=yuy[i];
                saki[yuy[i]]=2;
                yuu[yuy[i]][3]=yuy[i]+n;
            }
        }
        if(~solve()) return 0;
    }
    puts("-1");
    return 0;
}

2019年6月2日

おすすめ

転載: www.cnblogs.com/butterflydew/p/10964110.html