• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

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

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

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\n");
            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\n",anss);
    }
    return 0;
}

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
PHP设计模式-迭代器模式发布时间:2022-07-10
下一篇:
PHP控制前台弹出对话框发布时间:2022-07-10
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap