• 【xsy1058】 单词 乱搞


    题目大意:给你$n$个长度为$m$的字符串,字符集仅为{x,y,z}三个字符,定义两个字符串$(s_i,s_j)$的相似度为$sum_{k=1}^{m} [s_i[k]==s_j[k]]$。

    从$0$到$m$询问你相似度为i的字符串的对数。

    数据范围:$n imes m≤100000$(没错是乘号)

    此题的题解做法貌似是:分$m≤12$和$m>12$来做。

    先考虑$m≥12$的,考虑直接暴力判断,复杂度就是$O(mn^2)$的,显然是可以过的

    当$m≤12$时,我们做一个$dp$,令$f[i][j]$表示前$i$个字符串中,字符串为$j$的个数。

    考虑到字符集的大小,字符串的数量显然是$3^m$的

    时间复杂度:$O(n imes 3^{m})$。

    然而,这题的时限是3s,经过测试,我们发现当$m>2$时,都可以在$3s$内跑完。

    所以我们只需要特殊处理下$m=1$和$m=2$的情况就可以了。

    代码短了很多qwq

    (所以字符集是不是可以出大一些了呢)

     1 #include<bits/stdc++.h>
     2 #define M 100005
     3 #define L long long
     4 #define S(x) x*(x-1)/2
     5 using namespace std;
     6 char *c[M]={0};
     7 int n,m; L ans[M]={0};
     8 
     9 void solve1(){
    10     L cnt1=0,cnt2=0,cnt3=0;
    11     for(int i=1;i<=n;i++){
    12         if(c[i][0]=='x') cnt1++;
    13         if(c[i][0]=='y') cnt2++;
    14         if(c[i][0]=='z') cnt3++;
    15     }
    16     ans[1]=S(cnt1)+S(cnt2)+S(cnt3);
    17     ans[0]=cnt1*cnt2+cnt1*cnt3+cnt2*cnt3;
    18 }
    19 void solve2(){
    20     L cnt[3][3]={0};
    21     for(int i=1;i<=n;i++){
    22         int l,r;
    23         if(c[i][0]=='x') l=0;
    24         if(c[i][0]=='y') l=1;
    25         if(c[i][0]=='z') l=2;
    26         if(c[i][1]=='x') r=0;
    27         if(c[i][1]=='y') r=1;
    28         if(c[i][1]=='z') r=2;
    29         cnt[l][r]++;
    30     }
    31     for(int i=0;i<3;i++) for(int j=0;j<3;j++){
    32         ans[2]+=S(cnt[i][j]);
    33         for(int ii=0;ii<3;ii++) for(int jj=0;jj<3;jj++){
    34             int hh=(i==ii)+(j==jj); if(hh==2) continue;
    35             ans[hh]+=cnt[i][j]*cnt[ii][jj];
    36         }
    37     }
    38     ans[0]/=2; ans[1]/=2;
    39 }
    40 void solve3(){
    41     for(int i=1;i<=n;i++)
    42     for(int j=i+1;j<=n;j++){
    43         int cnt=0;
    44         for(int k=0;k<m;k++) cnt+=(c[i][k]==c[j][k]);
    45         ans[cnt]++;
    46     }
    47 }
    48     
    49 
    50 int main(){
    51     scanf("%d%d",&n,&m);
    52     for(int i=1;i<=n;i++){
    53         c[i]=new char[m];
    54         scanf("%s",c[i]);
    55     }
    56     if(m==1) solve1();
    57     if(m==2) solve2();
    58     if(m>=3) solve3();
    59     for(int i=0;i<=m;i++) printf("%lld
    ",ans[i]);
    60 }
  • 相关阅读:
    C#获取根目录的方法集合
    C# 获取文件MD5值的方法
    VS2015 搭建 Asp.net core 开发环境
    【Networking】容器网络大观 && SDN 资料汇总
    【Networking】flannel,pipework,weave,udp,vxlan,ovs等资料
    【K8s】Kubernetes 最近正在看的资料
    【GoLang】go 微服务框架 && Web框架学习资料
    【Eclipse】eclipse che 协作开发
    【Kubernetes】两篇文章 搞懂 K8s 的 fannel 网络原理
    【SpringBoot】SpringBoot 入门示例
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/10381093.html
Copyright © 2020-2023  润新知