正确答案

https://zybuluo.com/ysner/note/1174028

题面

外卡组试卷中共有\(m\)道判断题,小Y一共从其他\(n\)个神犇那问了答案。
\(n\)个神犇中有\(p\)个考了满分,\(q\)个考了零分,其他神犇不为满分或零分。
这可让小Y犯了难。你能帮助他们还原出标准答案吗?如有多解则输出字典序最小的那个。无解输出\(-1\)

  • \(n\leq30000,m\leq500\)

解析

很显然,我们可以把这些神犇的答案变成一堆\(01\)字符串。
然后若要标准答案,对这些字符串进行排序,找出个数恰好为\(p\)的和反过来个数恰好为\(q\)的字符串即可。

如何排序?
\(Tire\)(注意空间复杂度为\(O(mn)\),要卡空间)\(map\)都可以。
复杂度估计不超过\(O(100n)\)

如果\(p=0,q=0\),直接暴搜即可,复杂度不超过\(O(2n)\)
然而我不判有没有当前字符串才能AC是什么情况

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define ll long long
#define re register
#define il inline
#define fp(i,a,b) for(re int i=a;i<=b;i++)
#define fq(i,a,b) for(re int i=a;i>=b;i--)
using namespace std;
int n,m,p,q,a[30005][505],tot,id[15000005][2],num[15000005],now[600],f;
il ll gi()
{
  re ll x=0,t=1;
  re char ch=getchar();
  while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
  if(ch=='-') t=-1,ch=getchar();
  while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
  return x*t;
}
il void wri(re int x)
{
  if(x<0) putchar('-'),x=-x;
  if(x>9) wri(x/10);
  putchar(x%10+'0');
}
il void dfs(re int x,re int u,re int dep)
{
  if(dep==m) return;
  if(!a[x][dep+1])
    {
      if(!id[u][0]) id[u][0]=++tot,++num[tot];
      else ++num[id[u][0]];
      dfs(x,id[u][0],dep+1);
    }
  else
    {
      if(!id[u][1]) id[u][1]=++tot,++num[tot];
      else ++num[id[u][1]];
      dfs(x,id[u][1],dep+1);
    }
}
il int work(re int x,re int dep)
{
  if(dep==m) return num[x];
  re int way=now[dep]^1;
  if(id[x][way]) return work(id[x][way],dep+1);
  else return 0;
}
il void print()
{
  fp(i,0,m-1) putchar((now[i]^f)?'Y':'N');
  puts("");
  exit(0);
}
il void dfs1(re int x,re int dep)
{
  if(dep==m)
    { 
      if(num[x]!=p) return;
      if(work(0,0)==q) print();
      return;
    }
  if(id[x][0]) now[dep]=0,dfs1(id[x][0],dep+1);
  if(id[x][1]) now[dep]=1,dfs1(id[x][1],dep+1);
}
il void dfs2(re int x,re int dep)
{
  if(dep==m)
    {
      if(num[x]!=p) return;
      if(work(0,0)==q) print();
      return;
    }
  now[dep]=0,dfs2(id[x][0],dep+1);
  now[dep]=1,dfs2(id[x][1],dep+1);
}
int main()
{
  freopen("answer.in","r",stdin);
  freopen("answer.out","w",stdout);
  n=gi();m=gi();p=gi();q=gi();
  fp(i,1,n)
    fp(j,1,m)
    {
      re char ch=getchar();
      while(ch!='N'&&ch!='Y'){ch=getchar();}
      a[i][j]=(ch!='N');
    }
  fp(i,1,n) dfs(i,0,0);
  if(!p&&q) swap(p,q),f=1;
  if(p||q) dfs1(0,0);
  else dfs2(0,0);
  puts("-1");
  fclose(stdin);
  fclose(stdout);
  return 0;
}
posted @ 2018-06-06 19:26  小蒟蒻ysn  阅读(315)  评论(0编辑  收藏  举报