• 尺取法


    问题:给你一些数,请在这些数中找到一个区间,使得区间里每一个元素的和大于或等于给定的某个值。

    题目很简单并不难懂,很容易想到双重循环,枚举区间起点和终点,然后每一次都求一次和,再和给定的数作比较,效率低下。

    尺取法与它的模拟思路类似,都是寻找一个区间的起点和终点,但是一遍过高效的多。

    尺取法算法过程思路:

    用两个指针,最初都指向,这一组数中的第一个,然后如果这个区间的元素之和小于给定的数,就把右指针向右移(加数),直到区间和大于等于给定的值为止。然后开始更新答案取得最小值!把左指针向右移(减数),直到区间和等于给定的值为止,保存方案,继续操作。

    假如左指针指向这些数的第一个,并且右指针指向这组数的最后一个,这种情况下的子区间元素之和仍然小于给定的数的话,表示这个序列不可能大于等于某值s。

    本质也是一种模拟。用于解决:

    1.区间和问题

    2.求最小区间长度(满足。。条件的)

    模板例题poj3061

     1 #include <iostream>
     2 #include <string>
     3 #include <algorithm>
     4 using namespace std;
     5 typedef long long ll;
     6 const int maxn=1005;
     7 int a[maxn];
     8 
     9 int main()
    10 {
    11     ios::sync_with_stdio(false); cin.tie(0);
    12     
    13     int T;
    14     cin>>T;
    15     while(T--)
    16     {
    17         int n,s,ans=1e6+5;
    18         cin>>n>>s;
    19         for(int i=1;i<=n;i++)
    20         {
    21             cin>>a[i];
    22         }
    23         
    24         int sum=0,l=1,r=1;
    25         while(r<=n)
    26         {
    27             while(sum<s && r<=n)
    28             {
    29                 sum+=a[r];
    30                 r++;//r可能大于n,r总是指向当前的下一个 
    31             }
    32             
    33             while(sum>=s)
    34             {
    35                 ans=min(ans,r-l);//因为指向了下一个所以不用再+1 
    36                 sum-=a[l];
    37                 l++;
    38             }
    39         }
    40         if(l==1 && r>n)
    41         {
    42             cout<<'0'<<endl; 
    43         }
    44         else
    45         {
    46             cout<<ans<<endl;
    47         }
    48     }
    49     
    50     return 0;
    51 }

    牛客wannafly挑战赛22A

    分析和思路:
    求最小的满足条件的区间长度,一个数记录区间的开始---一个数记录末尾, 先移动末尾--满足条件后移动开始(缩小区间)。
    每次读入的时候就让 r 右移,如果最左边的出现过 l 右移,如果得到了num=26就可以更新答案。

     1 #include <iostream>
     2 #include <string>
     3 #include <algorithm>
     4 #include <map>
     5 #include <cstdio>
     6 #include <cstring>
     7 using namespace std;
     8 const int maxn=1e6+5;
     9 char s[maxn];
    10 int vis[maxn];
    11 
    12 int main()
    13 {
    14     ios::sync_with_stdio(false); cin.tie(0);
    15     
    16     cin>>s;
    17     
    18     int len=strlen(s),num=0,l=0,r=0,ans=1e6+5;
    19     while(r<=len-1)
    20     {
    21         while(num<26 && r<=len-1)//不满足条件一直右移 
    22         {
    23             if(a[s[r]-'a']==0)
    24             {
    25                 num++;
    26             }
    27             vis[s[r]-'a']++;
    28             r++;
    29         }
    30         while(num>=26)//满足一直更新答案,直到不满足寻找下一个 
    31         {
    32             ans=min(ans,r-l);
    33             vis[s[l]-'a']--;
    34             if(vis[s[l]-'a']==0) num--;
    35             l++;
    36         }
    37     }
    38     
    39     cout<<ans<<endl;
    40 
    41     
    42     return 0;
    43 }
  • 相关阅读:
    iOS开发CoreAnimation解读之三——几种常用Layer的使用解析
    iOS开发CoreAnimation解读之二——对CALayer的分析
    iOS开发CoreAnimation解读之一——初识CoreAnimation核心动画编程
    在最完整的搜索提示降史上的用户交互的研究——阅读《An Eye-tracking Study of User Interactions with Query Auto Completion》
    学习算法
    This Android SDK requires Android Developer Toolkit version 22.6.2 or above.
    一切都不是为了营销手段的目的都是耍流氓
    LeetCode219:Contains Duplicate II
    无尽的循环ViewPager
    允许Ubuntu14.04&quot;保存&quot;屏幕亮度值
  • 原文地址:https://www.cnblogs.com/redblackk/p/9568859.html
Copyright © 2020-2023  润新知