• http://acm.zzuli.edu.cn/zzuliacm/problem.php?cid=1158&pid=5 二分函数的间接应用


    Description

    小火山获得了一个字符串,然而大火山让小火山从里面截取一段字符串,并且让小火山截取的字符串满足一些字符达到一定数量。
    小火山觉得很容易,但是他想要知道他至少得截取多长的字符串。
    Input
    首先是一个整数t(t<=100),表示测试数据组数。接下来是两个整数n和m(n<=10000, m<=10),n表示字符串的长度,m表示要满足一定数量的字符
     
    的种类.(字符只包含小写英文字母)
    个数(没有重复字符种类),然后有m行,每行第一个是一个字符,然后是一个整数x(x<=50),表示这种字符的的要求数量。

    Output

    输出最小长度,如果达不到要求输出-1

    Sample Input

    1
    6 3
    cancan
    c 2
    a 2
    n 2

    Sample Output

    6
     
     
    一道很好的二分函数的直接应用   因为设计了多个单词的查找   变比一般的难上一点    
    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<math.h>
    #define LL long long
    using namespace std;
    #define INF 0x3f3f3f3f
    #define N 10009
    char str1[N];
    int qq[30][N];
    struct node
    {
        int w,a,ww;
        char str[12];
    }q[N];
    int main()
    {
        int T,n,m;
        scanf("%d",&T);
        while(T--)
        {
            memset(q,0,sizeof(q));
            scanf("%d%d%s",&n,&m,str1);
            for(int i=0;i<m;i++)
            {
                scanf("%s%d",q[i].str,&q[i].a);
                q[i].w=q[i].str[0]-'a';////q[i].w主要是转换成数字 ,方便下面的应用
            }
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<m;j++) ///qq[q[j].w][i]按照递增,方便二分查找
                {
                    if(str1[i]==q[j].str[0]) ///统计q[j].ww ,比较a[i]  提前判断-1的情况
                        q[j].ww++;
                    if(i==0)
                    {
                        if(str1[i]==q[j].str[0]) qq[q[j].w][i]=1;
                        else qq[q[j].w][i]=0;
                    }
                    else if(str1[i]==q[j].str[0])
                        qq[q[j].w][i]=qq[q[j].w][i-1]+1;
                    else
                        qq[q[j].w][i]=qq[q[j].w][i-1];
                }
            }
            int s=0;
            for(int i=0;i<m;i++)
                if(q[i].ww<q[i].a)
                s=1;
            if(s==1)///特殊情况的输出
            {
                printf("-1
    ");
                continue;
            }
            int anss=INF,ans;
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<m;j++)
                {
                    if(str1[i]==q[j].str[0])
                    {
                        int e=i,ss=0;
                        if(qq[q[j].w][n-1]-q[j].a+1<qq[q[j].w][i])///判断后面是否还够所需要的个数
                        {
                            ss=1;
                            break;
                        }
                        ans=lower_bound(qq[q[j].w],qq[q[j].w]+n,qq[q[j].w][i]+q[j].a-1)-qq[q[j].w];///利用二分查找,已知当前出现是第几个,在往后找第所需要的个数
                        for(int k=j+1;k<m+j;k++)///利用for把所需要的个数全部遍历,在其中找到最近的也是最优的
                        {
                            int kk=k%m;
                            if(qq[q[kk].w][n-1]-q[kk].a<qq[q[kk].w][i])///判断后面是否还够所需要的个数
                            {
                                ss=1;
                                 break;
                            }
                            ans=max(ans,lower_bound(qq[q[kk].w],qq[q[kk].w]+n,q[kk].a+qq[q[kk].w][i])-qq[q[kk].w]);///同上
                        }
                        if(ss==0)
                        anss=min(anss,ans-e+1);
                    }
                }
            }
            printf("%d
    ",anss);
        }
        return 0;
    }
  • 相关阅读:
    mysql事件之修改事件(ALTER EVENT)&禁用事件(DISABLE)&启用事件(ENABLE)&事件重命名&数据库事件迁移
    用Sqoop进行Hive和MySQL之间的数据互导
    Sqoop使用手册
    azkaban使用案例
    azkaban3.x安装
    工作流调度器azkaban概述
    将 Hive 空值统一为 N
    [模拟] [洛谷] P1765 手机
    [NYISTOJ] 题目845 无主之地1
    [NYISTOJ] 题目 458 小光棍数
  • 原文地址:https://www.cnblogs.com/a719525932/p/5758330.html
Copyright © 2020-2023  润新知