尺取法:顾名思义就是像尺子一样一段一段去取,保存每次的选取区间的左右端点。然后一直推进

解决问题的思路:

  1. 先移动右端点 ,右端点推进的时候一般是加
  2. 然后推进左端点,左端点一般是减

poj 2566

题意:从数列中找出连续序列,使得和的绝对值与目标数之差最小

思路:

  1. 在原来的数列开头添加一个0
  2. 每次找到的区间为 [min(i,j)+1,max(i,j)]

应用尺取法的代码:

 while (r <=n)
{
int sub = pre[r].sum - pre[l].sum;
while (abs(sub - t) < Min)
{
Min = abs(sub - t);
ansl= min(pre[l].id, pre[r].id) + ;
ansr = max(pre[l].id, pre[r].id);
ans = sub;
}
if (sub < t)
r++;
else if (sub > t) l++;
else break;
if (l == r) r++;
}

解决问题的代码:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int N = 1e5 + ;
const int INF = 0x7fffffff;
int n, k;
int a[N];
struct node {
int sum, id;
}pre[N];
bool cmp(node a, node b)
{
return a.sum < b.sum;
}
int main()
{
while (scanf("%d%d", &n, &k) != EOF)
{
if (n == && k == ) break;
pre[].id = , pre[].sum = ;
for (int i = ; i <= n; i++)
{
scanf("%d", &a[i]);
pre[i].id = i;
pre[i].sum = pre[i - ].sum + a[i];
}
sort(pre, pre + n + , cmp);
for (int i = ; i < k; i++)
{
int t;
scanf("%d", &t);
int Min = INF;
int l = , r = ;
int ans, ansl, ansr;
while (r <=n)
{
int sub = pre[r].sum - pre[l].sum;
while (abs(sub - t) < Min)
{
Min = abs(sub - t);
ansl= min(pre[l].id, pre[r].id) + ;
ansr = max(pre[l].id, pre[r].id);
ans = sub;
}
if (sub < t)
r++;
else if (sub > t) l++;
else break;
if (l == r) r++;
}
printf("%d %d %d\n", ans, ansl, ansr);
}
}
return ;
}

poj 2739

题意:将一个整数分解为连续的素数之和,有多少种分法?

思路:

  1. 打表,先打出素数表
  2. 然后依次查询是否满足条件

用尺取法的代码:

 for (;;) {
while (r < size&&sum < n)
{
sum += primes[r++];
}
if (sum < n) break;
else if (sum == n) result++;
sum -= primes[l++];
}

解决问题的代码:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
#define maxn 10000+16
vector<int> primes;
vector<bool> is_prime;
void init_prime()
{
is_prime = vector<bool>(maxn + , true);
is_prime[] = is_prime[] = false;
for (int i = ; i < maxn; i++)
{
if (is_prime[i])
{
primes.push_back(i);
for (int j = i * ; j < maxn; j += i)
{
is_prime[j] = false;
}
}
}
}
int main()
{
int n;
init_prime();
int size = primes.size();
while (cin >> n && n)
{
int result = , sum = ;
int l = ,r = ;
for (;;) {
while (r < size&&sum < n)
{
sum += primes[r++];
}
if (sum < n) break;
else if (sum == n) result++;
sum -= primes[l++];
}
printf("%d\n", result);
}
return ;
}

poj 2100

题意:将一个整数分解为连续数平方之和,有多少种分法?

解决问题的思路:

  1. 右端点移动,sum+=r*r;
  2. 如果满足答案就 push (l,r)
  3. 左端点移动 sum-=l*l;

用尺取法的代码:

 for (;;)
{
while (sum < n)
{
sq = r * r;
sum += sq;
r++;
}
if (sq > n) break;
else if (sum == n) ans.push_back(make_pair(l, r));
sum -= l * l;
l++;
}

解决问题的代码:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <cstring>
#include <vector>
#include <queue>
using namespace std; typedef long long ll;
vector<pair<ll, ll>> ans;
void solve(ll n)
{
ll l = , r = , sum = , sq;
for (;;)
{
while (sum < n)
{
sq = r * r;
sum += sq;
r++;
}
if (sq > n) break;
else if (sum == n) ans.push_back(make_pair(l, r));
sum -= l * l;
l++;
}
ll size = ans.size();
printf("%lld\n", size);
for (ll i = ; i < size; i++)
{
ll ansr = ans[i].second;
ll ansl = ans[i].first;
printf("%lld",ansr-ansl);
for (ll j=ansl;j<ansr;j++)
printf(" %lld", j);
printf("\n");
}
} int main()
{
ll n;
while (scanf("%lld", &n) != EOF)
{
if (n == ) break;
solve(n);
}
return ;
}

尺取法 poj 2566的更多相关文章

  1. 尺取法 POJ 3320 Jessica's Reading Problem

    题目传送门 /* 尺取法:先求出不同知识点的总个数tot,然后以获得知识点的个数作为界限, 更新最小值 */ #include <cstdio> #include <cmath> ...

  2. 尺取法 POJ 3601 Subsequence

    题目传送门 /* 题意:求连续子序列的和不小于s的长度的最小值 尺取法:对数组保存一组下标(起点,终点),使用两端点得到答案 1. 记录前i项的总和,求[i, p)长度的最小值,用二分找到sum[p] ...

  3. POJ 3061 Subsequence 尺取法 POJ 3320 Jessica's Reading Problem map+set+尺取法

    Subsequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13955   Accepted: 5896 Desc ...

  4. 尺取法 || POJ 2739 Sum of Consecutive Prime Numbers

    给一个数 写成连续质数的和的形式,能写出多少种 *解法:先筛质数 然后尺取法 **尺取法:固定区间左.右端点为0,如果区间和比目标值大则右移左端点,比目标值小则右移右端点               ...

  5. poj 2566 Bound Found(尺取法 好题)

    Description Signals of most probably extra-terrestrial origin have been received and digitalized by ...

  6. poj 2566"Bound Found"(尺取法)

    传送门 参考资料: [1]:http://www.voidcn.com/article/p-huucvank-dv.html 题意: 题意就是找一个连续的子区间,使它的和的绝对值最接近target. ...

  7. POJ 2566 Bound Found(尺取法,前缀和)

    Bound Found Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5207   Accepted: 1667   Spe ...

  8. poj 2566 Bound Found 尺取法 变形

    Bound Found Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 2277   Accepted: 703   Spec ...

  9. POJ 尺取法

    poj3061 Subsequence 题目链接: http://poj.org/problem?id=3061 挑战P146.题意:给定长度为n的数列整数a0,a1,...,a(n-1)以及整数S, ...

随机推荐

  1. angular2-搭建环境

    npm  模块将被下载安装到[全局目录]中.[全局目录]通过 npm config set prefix "目录路径" 来设置.通过 npm config get prefix 来 ...

  2. select标签使用 三目运算符

    <td> <select id="roleName" name="roleName" class="input" styl ...

  3. 对数组排序进行"洗牌"(随机排序)

    这段代码在这里使用Fisher Yates洗牌算法给一个指定的数组进行洗牌(随机排序). function shuffle(arr) {     var i,        j,        tem ...

  4. C++ VS编译问题--LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

    用VS编译时,当出现错误LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏: 这个问题的解决方案为: 1. 找到项目\xx属性\配置属性\清单工具\输 ...

  5. 初识QT中的qDebug()

    首先在头文件中包含 #include<QDebug> 当开发者需要为一个装置.文件.字符串或者控制台,写出调试和跟踪信息时,该类被使用. 在需要使用的地方插入: qDebug(][]); ...

  6. ios视图层次结构

    原文:http://blog.csdn.net/xingboss3/article/details/7890238 UIView表示屏幕上的一块矩形区域,它在App中占有绝对重要的地位,因为IOS中几 ...

  7. 旋度定理(Curl Theorem)和散度定理(Divergence theorem)

    原文链接 首先说说格林公式(Green's theorem).对于一段封闭曲线,若其围城的区域D为单连通区域(内部任意曲线围城的区域都属于院区域),则有如下公式: 其中其中L为D的边界,取正方向.如果 ...

  8. caffe的损失函数

    损失函数,一般由两项组成,一项是loss term,另外一项是regularization term. J=L+R 先说损失项loss,再说regularization项. 1. 分对得分1,分错得分 ...

  9. python基本使用时常见错误

    python基本使用时常见错误 字符编码错误 如果要学习计算机编程语言,首先就要搞懂字符编码,否则在以后的学习过程中,将会是一场噩梦.在一开始使用的时候,我就遇到了很多的关于字符编码的问题,做个简单的 ...

  10. OOM导致的备库raylog损坏导致主从复制异常

    问题发现告警数据库出现复制中断,延迟超过100秒 问题排查复制信息检查,通过’show slave status\G’命令可以查看复制线程详细的工作状态,对于判断复制中断的原因有一些指导性意义.当时的 ...