• 尺取法


    一般是在给的一组数据中找到不大于某一个上限的“最优连续子序列”
    给长度为n的数组和一个整数m,求总和不小于m的连续子序列的最小长度;

    吃取法的基本思路是设置起始点与末尾点,然后末尾点不断自增直到满足一定条件,然后把该条件的一些情况记录,再把起始点自增,直到不满足条件,再自增末尾点,继续前面的,直到出界

    1.延展尾点
    2.退出条件
    3.收缩前点

    给出一个数组,求总和不小于m的连续子序列的最小长度

    传送门
    给出一个数组,求总和不小于m的连续子序列的最小长度

    #include <iostream>
    #include <cstdio>
    #define ll long long
    #define INF 0x3f3f3f3f
    using namespace std;
    const int N=1e5+5;
    int main(){
        int t,s,n;
        cin>>t;
        int a[N];
        while(t--){
            cin>>n>>s;
            for(int i=0;i<n;i++){scanf("%d",&a[i]);}
            int st=0,en=0;//下标,st表示起始位置,en表示末尾位置
            int ans=INF,sum=0;//ans表示答案,sum表示当前
            while(1){
                while(en<n&&sum<s)sum+=a[en++];
                if(sum<s)break;//因为前面while语句使得一直满足sum>=s,直到整个式子都没有这个情况了就退出
                ans=min(ans,en-st);//求取最短的子序列长度
                sum-=a[st++];
            }
            if(ans==INF)ans=0;
            printf("%d
    ",ans);
        }
        return 0;
    }
    

    一本书有p页,每页有一个知识点,求最少页数覆盖所有知识点

    传送门
    同上面一题,不同的是加了set求知识点的总数以及map求每个知识点的个数
    然后相同的方法即可

    /*
    一本书有p页,每页有一个知识点,求最少页数覆盖所有知识点
    */
    #include <iostream>
    #include <cstdio>
    #include <set>
    #include <map>
    #define INF 0x3f3f3f3f
    using namespace std;
    const int maxn=1e6+5;
    int a[maxn];
    std::map<int, int> cnt;
    set<int> t;
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
            t.insert(a[i]);
        }
        int num=t.size();//全部知识点
        int en=0,st=0;//st表示开始下标,en表示结束下标
        int sum=0;//目前学的知识点
        int ans=INF;//求最短的
        while(1){
            while(en<n&&sum<num){//扩展右边
                if(cnt[a[en++]]++==0)sum++;//没出现过的知识点进行记录,直到退出或者一段区间包含整个知识点
            }
            if(sum<num)break;//一般来说,从sum<num的循环中退出是不会执行这句,但从en<n退出表示都不满足条件了
            ans=min(ans,en-st);//此时[st,en]必定是满足条件的
            if(--cnt[a[st++]]==0)sum--;//缩短前面,如果在st后面还会出现的话,就缩短前面
        }
        printf("%d
    ",ans);
    
        return 0;
    }
    /**
    *set储存的是一串不重复的元素集合,且自动按照字典序进行排序
    *insert()插入元素,size()获取元素个数,与map不同的是,map一对一地还存储了该元素的个数
    */
    

    由连续素数相加为n的种类


    埃氏素数筛+尺取法

    #include <iostream>
    #include <cstdio>
    using namespace std;
    const int maxn=1e4+5;
    int prime[maxn];
    int isprime[maxn];
    int init(){
        for(int i=0;i<maxn;i++)isprime[i]=i;
        int k=0;
        isprime[0]=isprime[1]=0;
        for(int i=2;i<=maxn;i++){
            if(isprime[i]){
                prime[k++]=i;
                for(int j=2*i;j<=maxn;j+=i){
                    isprime[j]=0;
                }
            }
        }
        return k;
    }
    int main(){
        int cnt=init();
        int n,k;
        while(~scanf("%d",&n)){
            if(n==0)break;
            int st=0,en=0;
            int sum=0;
            int ans=0;
            while(1){
                while(en<cnt&&sum<n)sum+=prime[en++];
                if(sum<n)break;
                if(sum==n)ans++;
                sum-=prime[st++];
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    

    平分和为n的情况

    传送门

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #define ll long long
    using namespace std;
    struct node{
        ll st,en;
    };
    vector<node> v;
    int main(){
        ll n;
        while(~scanf("%lld",&n)){
            v.clear();
            ll st=1,en=1;
            ll sum=0;
            while(1){
                while(en*en<=n&&sum<n){sum+=(en*en);en++;}
                if(sum<n)break;
                if(sum==n)v.push_back((node){st,en-1});
                sum-=st*st;st++;
       
            }
            ll num=v.size();
            printf("%lld
    ",num );
            for(int i=0;i<num;i++){
                printf("%lld",v[i].en-v[i].st+1);
                for(ll k=v[i].st;k<=v[i].en;k++)printf(" %lld",k);
                putchar('
    ');
            }
        }
        return 0;
    }
    
    
    
  • 相关阅读:
    消息队列设计
    抓包工具Fiddler
    分布式系统和CAP
    Topshelf组件
    Parallel.For
    MVC插件
    Azure Messaging-ServiceBus Messaging
    MVC
    requireJS
    第一次react-native项目实践要点总结 good
  • 原文地址:https://www.cnblogs.com/Emcikem/p/11429280.html
Copyright © 2020-2023  润新知