{"oj":"poj","problem_id":"3061","title":"Subsequence","tags":["双指针"],"md_path":"poj/poj3061.md","url":"/problems/poj/3061","html_content":"<div class=toc-body><div class=\"toc-title\">\n        <h3>目录</h3>\n</div>\n<div class=\"toc-content\"></div></div><p>求数字串中连续子序列的最小长度，要求这个子序列的和至少得大于等于S。</p>\n<div class=\"language-clike line-numbers-mode\"><div class=\"code-info-header\"><span>cpp</span></div><pre><code class=\"language-cpp\">#include <span class=\"token operator\">&lt;</span>iostream<span class=\"token operator\">></span>\nusing namespace std<span class=\"token punctuation\">;</span>\nconst int maxn <span class=\"token operator\">=</span><span class=\"token number\">2e5</span><span class=\"token punctuation\">;</span>  <span class=\"token comment\">// 数组最大长度</span>\nint a<span class=\"token punctuation\">[</span>maxn<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>          <span class=\"token comment\">// 存储正整数序列</span>\nlong long n <span class=\"token punctuation\">,</span>s<span class=\"token punctuation\">;</span>       <span class=\"token comment\">// n: 序列长度, s: 目标和</span>\n\nint main <span class=\"token punctuation\">(</span>int argc<span class=\"token punctuation\">,</span> char <span class=\"token operator\">*</span>argv<span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    int T<span class=\"token punctuation\">;</span>  <span class=\"token comment\">// 测试用例数量</span>\n    std<span class=\"token punctuation\">:</span><span class=\"token punctuation\">:</span>cin <span class=\"token operator\">></span><span class=\"token operator\">></span> T<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>T<span class=\"token operator\">--</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        std<span class=\"token punctuation\">:</span><span class=\"token punctuation\">:</span>cin <span class=\"token operator\">></span><span class=\"token operator\">></span> n <span class=\"token operator\">></span><span class=\"token operator\">></span> s<span class=\"token punctuation\">;</span>  <span class=\"token comment\">// 读取序列长度n和目标和s</span>\n        \n        <span class=\"token comment\">// 读取序列中的每个正整数</span>\n        <span class=\"token keyword\">for</span><span class=\"token punctuation\">(</span>int i <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span>i <span class=\"token operator\">&lt;=</span> n <span class=\"token punctuation\">;</span><span class=\"token operator\">++</span>i <span class=\"token punctuation\">)</span> <span class=\"token comment\">// i: 1->n</span>\n        <span class=\"token punctuation\">{</span>\n            std<span class=\"token punctuation\">:</span><span class=\"token punctuation\">:</span>cin <span class=\"token operator\">></span><span class=\"token operator\">></span> a<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n        \n        int ans <span class=\"token operator\">=</span> n<span class=\"token operator\">+</span><span class=\"token number\">1</span><span class=\"token punctuation\">;</span>    <span class=\"token comment\">// 答案初始化为不可能的值(n+1)，表示还没找到解</span>\n        int i <span class=\"token operator\">=</span> <span class=\"token number\">1</span> <span class=\"token punctuation\">,</span>j <span class=\"token operator\">=</span> <span class=\"token number\">1</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// 滑动窗口的左右指针，初始都指向第一个元素</span>\n\n        long long sum <span class=\"token operator\">=</span> a<span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>  <span class=\"token comment\">// 当前窗口的和，初始为第一个元素</span>\n        \n        <span class=\"token comment\">// 滑动窗口主循环，右指针不超过数组边界</span>\n        <span class=\"token keyword\">while</span><span class=\"token punctuation\">(</span> j <span class=\"token operator\">&lt;=</span> n<span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span> sum <span class=\"token operator\">>=</span>s<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n                <span class=\"token comment\">// 当前窗口和>=目标值，尝试更新答案</span>\n                <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>ans <span class=\"token operator\">></span> j<span class=\"token operator\">-</span>i<span class=\"token operator\">+</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span> ans <span class=\"token operator\">=</span> j<span class=\"token operator\">-</span>i<span class=\"token operator\">+</span><span class=\"token number\">1</span><span class=\"token punctuation\">;</span>  <span class=\"token comment\">// 更新最小长度</span>\n                \n                <span class=\"token comment\">// 收缩窗口：移除左边界元素，左指针右移</span>\n                sum <span class=\"token operator\">-</span><span class=\"token operator\">=</span>a<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n                i<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span>\n            <span class=\"token punctuation\">}</span>\n            <span class=\"token keyword\">else</span> <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span> sum <span class=\"token operator\">&lt;</span> s<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n                <span class=\"token comment\">// 当前窗口和&lt;目标值，需要扩展窗口</span>\n                j<span class=\"token operator\">++</span><span class=\"token punctuation\">;</span>                    <span class=\"token comment\">// 右指针右移</span>\n                sum <span class=\"token operator\">+</span><span class=\"token operator\">=</span>a<span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>            <span class=\"token comment\">// 加入新元素到窗口和</span>\n            <span class=\"token punctuation\">}</span>\n        <span class=\"token punctuation\">}</span>\n        \n        <span class=\"token comment\">// 如果答案还是初始值，说明没找到满足条件的子序列，输出0</span>\n        <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span> ans <span class=\"token operator\">==</span> n <span class=\"token operator\">+</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span> ans <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n        std<span class=\"token punctuation\">:</span><span class=\"token punctuation\">:</span>cout <span class=\"token operator\">&lt;</span><span class=\"token operator\">&lt;</span> ans <span class=\"token operator\">&lt;</span><span class=\"token operator\">&lt;</span> <span class=\"token string\">\"\\n\"</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n</code></pre></div>\n","md_content":"\n[[TOC]]\n\n求数字串中连续子序列的最小长度，要求这个子序列的和至少得大于等于S。\n\n@include-code(./poj3061.cpp, cpp)\n"}