• 牛客训练41D最小相似度bfs


    最小相似度

      题目大意:对于位数相同的两个二进制串,SIM(A,B)为它们的相似度,也就是A^B中0的个数。现在给定一堆串,找出一个T使得max{SIM(S1,T),SIM(S2,T),......,SIM(Sn,T)}最小,不过不用输出T,只需要输出那个最小值

    正解应该是FWT,不过没学过,所以也没做出来,而给出的题解的是用bfs做的,还真没想到能够用搜索做,刚开始看也不理解,不过研究了一下还是,挺好理解的。

      首先,也是为什么可以用bfs的一点,就是串的长度最大只到20,也就是220=1048576种状态,可以通过bfs来遍历,那接下来怎么搜,搜什么呢?

      相似度是A^B中0的个数,但0的个数我们并不好控制,但我们可以控制1的个数,也就是不相似度usim。像(1<<i)就是1在第i位,其他位都是0,那么B=A^(1<<i)的话,B就是A不相似度为1的串,而再有C=B(1<<i)并且C!=A的话,C就是A不相似度为2的串,所以我们就可以像bfs一样一层一层的找到最大的不相似度。而对于多个串的话,就是多起点bfs了。

      那为什么这样可以使,答案刚好是跟多个串的不相似度中的最大的呢?像A=111,B=001的话,A的最大不相似的串是000,但A要第3层才能遍历到000,B第1层就能遍历到000,这样像两边往中间逼近一样,能遍历到的最大的那个不相似度就是对于所有串来说的最大不相似度

      最后,再拿长度减去最大不相似度就可以得到最小相似度了,详情见代码

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<queue>
     4 using namespace std;
     5 const int N=1<<21;
     6 char s[28];
     7 int n,m,usim[N];
     8 int main()
     9 {
    10     memset(usim,-1,sizeof(usim));
    11     scanf("%d%d",&n,&m);
    12     queue<int> q;
    13     for(int i=0;i<n;i++)
    14     {
    15         scanf("%s",s);
    16         int x=0;
    17         for(int j=0;j<m;j++)
    18             x=(x<<1)|(s[j]-'0');//将串转换成数字表示状态 
    19         if(usim[x]==-1)
    20         {
    21             usim[x]=0;//自己和自己的不相似度为0 
    22             q.push(x);//多起点 
    23         }
    24     }
    25     int ans=0;
    26     while(!q.empty())
    27     {
    28         int x=q.front();
    29         q.pop();
    30         if(usim[x]>ans)
    31             ans=usim[x];//找到最大不相似度 
    32         for(int i=0;i<m;i++)
    33         {
    34             int y=x^(1<<i);//y是x第i位取反的结果 
    35             if(usim[y]==-1)
    36             {
    37                 usim[y]=usim[x]+1;//所以y与起点串的不相似度就是x的+1 
    38                 q.push(y);
    39             }
    40         }
    41     }
    42     printf("%d
    ",m-ans);
    43     return 0; 
    44 }
    再偷懒就就就自己打自己
  • 相关阅读:
    使用visio 2007对现有的数据库进行反向工程
    GOOGLE地图坐标拾取方法、GOOGLE地图获取坐标方法
    Visio 2007中进行数据库建模时如何显示字段类型以及概念名称
    WCF把书读薄(4)——事务编程与可靠会话
    WCF把书读薄(3)——数据契约、消息契约与错误契约
    WCF把书读薄(2)——消息交换、服务实例、会话与并发
    Backbone.js developer 武汉 年薪8w-10w
    Java面试
    从pb文件中恢复计算图并在tensorboard中展示
    Ubuntu下解决u盘变成只读模式
  • 原文地址:https://www.cnblogs.com/LMCC1108/p/10470798.html
Copyright © 2020-2023  润新知