尺取法

尺取法;应用于有这么一类问题,需要在给的一组数据中找到不大于某一个上限的“最优连续子序列”
HDU5672
给你一个1e6的字符串,问你有多少个连续子串的至少包含不同的k个字母。

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
char s[1000005];
int c[30],k;
int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        scanf("%s%d",s,&k);
        memset(c,0,sizeof(c));
        int l=0,r=0,cnt=0,len=strlen(s);
        long long ans=0;
        while(l<=r)
        {
            while(cnt<k&&r<len)
            {
                c[s[r]-'a']++;
                if(c[s[r]-'a']==1) cnt++;
                r++;
            }
            if(cnt<k) break;
            ans+=(len-r+1);
            c[s[l]-'a']--;
            if(c[s[l]-'a']==0) cnt--;
            l++;
        }
        printf("%lld\n",ans);
    }
}

poj 3061
求连续子序列的和大于等于一个k值的最小区间长度。

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int a[100005];
int main()
{
    int t;scanf("%d",&t);
    while(t--)
    {
        int n,k;
        scanf("%d%d",&n,&k);
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        int l=0,r=0,sum=0,ans=n+1;
        while(l<=r)
        {
            while(r<n&&sum<k)
            {
                sum+=a[r];
                r++;
            }
            if(sum<k) break;
            ans=min(ans,r-l);
            sum-=a[l++];
        }
        if(ans==n+1) puts("0");
        else printf("%d\n",ans);
    }
}

pku2100
给你一个n(1e14),求连续整数的和等于n.

#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
using namespace std;
typedef long long ll;
vector<pair<int,int> > ans;
int main()
{
    ll n;
    scanf("%lld",&n);
    ll l=1,r=1,sum=0;
    while(l*l<=n)
    {
        while(r*r<=n&&sum<n)
        {
            sum+=r*r;
            r++;
        }
        if(sum==n) {ans.push_back(make_pair(l,r));}
        if(sum<n) break;
        sum-=l*l;
        l++;
    }
    printf("%d\n",(int)ans.size());
    for(int i=0;i<ans.size();i++)
    {
        printf("%d",ans[i].second-ans[i].first);
        for(int j=ans[i].first;j<ans[i].second;j++)
            printf(" %d",j);
        puts("");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值