zoukankan      html  css  js  c++  java
  • 计蒜客-第五场初赛-第二题 UCloud 的安全秘钥(简单)

    每个 UCloud 用户会构造一个由数字序列组成的秘钥,用于对服务器进行各种操作。作为一家安全可信的云计算平台,秘钥的安全性至关重要。因此,UCloud 每年会对用户的秘钥进行安全性评估,具体的评估方法如下:

    首先,定义两个由数字序列组成的秘钥 aa 和 bb近似匹配(approx≈) 的关系。aa 和 bb 近似匹配当且仅当同时满足以下两个条件:

    • |a|=|b|a=b∣,即 aa 串和 bb 串长度相等。
    • 对于每种数字 cc,cc 在 aa 中出现的次数等于cc 在 bb 中出现的次数。

    此时,我们就称 aa 和 bb 近似匹配,即 a approx bab。例如,(1,3,1,1,2)approx(2,1,3,1,1)(1,3,1,1,2)(2,1,3,1,1)。

    UCloud 每年会收集若干不安全秘钥,这些秘钥组成了不安全秘钥集合 TT。对于一个秘钥 ss 和集合 TT 中的秘钥 tt 来说,它们的相似值定义为:ss 的所有连续子串中与 tt 近似匹配的个数。相似值越高,说明秘钥 ss 越不安全。对于不安全秘钥集合 TT 中的每个秘钥 tt,你需要输出它和秘钥 ss 的相似值,用来对用户秘钥的安全性进行分析。

    输入格式

    第一行包含一个正整数 nn,表示 ss 串的长度。

    第二行包含 nn 个正整数 s_1,s_2,...,s_n(1leq s_ileq n)s1​​,s2​​,...,sn​​(1si​​n),表示 ss 串。

    接下来一行包含一个正整数 mm,表示询问的个数。

    接下来 mm 个部分:

    每个部分第一行包含一个正整数 k(1leq kleq n)k(1kn),表示每个 tt 串的长度。

    每个部分第二行包含 kk 个正整数 t_1,t_2,...,t_k(1leq t_ileq n)t1​​,t2​​,...,tk​​(1ti​​n),表示 TT 中的一个串 tt。

    输入数据保证 TT 中所有串长度之和不超过 200000200000。

    对于简单版本:1leq n,mleq 1001n,m100;

    对于中等版本:1leq nleq 50000,1leq mleq 5001n50000,1m500;

    对于困难版本:1 le n le 50000, 1 le m le 1000001n50000,1m100000。

    输出格式

    输出 mm 行,每行一个整数,即与 TT 中每个串 tt近似匹配的 ss 的子串数量。

    样例解释

    对于第一个询问,(3,2,1,3)approx(2,3,1,3)(3,2,1,3)(2,3,1,3),(3,2,1,3)approx(3,1,3,2)(3,2,1,3)(3,1,3,2);

    对于第二个询问,(1,3)approx(3,1)(1,3)(3,1),(1,3)approx(1,3)(1,3)(1,3);

    对于第三个询问,(3,2)approx(2,3)(3,2)(2,3),(3,2)approx(3,2)(3,2)(3,2)。

    样例输入

    5
    2 3 1 3 2
    3
    4
    3 2 1 3
    2
    1 3
    2
    3 2

    样例输出

    2
    2
    2
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<vector>
    #include<cmath>
    #include<algorithm>
    #define maxn 50010
    using namespace std;
    int a[maxn];
    int b[maxn], c[maxn],d[maxn];
    int T, n, m, num;
    int main()
    {
        cin >> n;
        int p = 0;
        for(int i=0; i<n; i++)
        {
            cin >> a[i];
            d[p++] = a[i];
        }
        cin >> T;
        while( T -- )
        {
            cin >> m;
            memset(b, 0, sizeof(b));
            for(int i=0; i<m; i++)
            {
                cin >> num;
                b[num] ++;
            }
            int sum = 0;
            for(int i=0; i<=n-m; i++)//枚举到n-m即枚举了所有可能
            {
                memset(c, 0, sizeof(c));
                for(int j=0; j<m; j++)
                {
                    c[a[i+j]]++;
                }
                int flag = 1;
                for(int i=0; i<p; i++)
                {
                    if( b[d[i]]!=c[d[i]] )
                    {
                        flag = 0;
                        break;
                    }
                }
                if( flag )
                    sum++;
            }
            cout << sum << endl;
        }
        return 0;
    }

    对于一个长度为 lenlen 的询问,枚举 ss 的一个长度为 lenlen 的子串,然后暴力检验两个集合是否相同即可。

    时间复杂度 O(n^2m)O(n2​​m)。

    彼时当年少,莫负好时光。
  • 相关阅读:
    关于maven的一些记录
    3des和tomcat部署
    java串口通讯
    mina自定义编解码
    Linux 下关闭防火墙设置
    查看本机IP
    linux修改localhost方法
    centos 6.5下使用中文输入法
    linux:can't save files
    ng-model取不到值的问题
  • 原文地址:https://www.cnblogs.com/l609929321/p/6938584.html
Copyright © 2011-2022 走看看