• 正确答案


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

    题面

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

    • (nleq30000,mleq500)

    解析

    很显然,我们可以把这些神犇的答案变成一堆(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;
    }
    
  • 相关阅读:
    学习笔记—Node之读取流的使用与实现
    macbook双系统用U盘离线安装 win10
    CF1634E Fair Share
    CF1632E Distance Tree
    CF1630D Flipping Range
    K8S部署之VMWare网络拓扑踩坑
    ArrayList中的遍历删除
    postgresql提权
    Sqlite数据库的Update知多少?
    C#屏蔽系统热键Ctrl+Alt+Delete的代码尝试。(已修改bug)
  • 原文地址:https://www.cnblogs.com/yanshannan/p/9146883.html
Copyright © 2020-2023  润新知