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

解决问题的思路:

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

poj 2566

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

思路:

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

应用尺取法的代码:

  1. while (r <=n)
  2. {
  3. int sub = pre[r].sum - pre[l].sum;
  4. while (abs(sub - t) < Min)
  5. {
  6. Min = abs(sub - t);
  7. ansl= min(pre[l].id, pre[r].id) + ;
  8. ansr = max(pre[l].id, pre[r].id);
  9. ans = sub;
  10. }
  11. if (sub < t)
  12. r++;
  13. else if (sub > t) l++;
  14. else break;
  15. if (l == r) r++;
  16. }

解决问题的代码:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <algorithm>
  4. #include <math.h>
  5. #include <cstring>
  6. #include <vector>
  7. #include <queue>
  8. using namespace std;
  9. const int N = 1e5 + ;
  10. const int INF = 0x7fffffff;
  11. int n, k;
  12. int a[N];
  13. struct node {
  14. int sum, id;
  15. }pre[N];
  16. bool cmp(node a, node b)
  17. {
  18. return a.sum < b.sum;
  19. }
  20. int main()
  21. {
  22. while (scanf("%d%d", &n, &k) != EOF)
  23. {
  24. if (n == && k == ) break;
  25. pre[].id = , pre[].sum = ;
  26. for (int i = ; i <= n; i++)
  27. {
  28. scanf("%d", &a[i]);
  29. pre[i].id = i;
  30. pre[i].sum = pre[i - ].sum + a[i];
  31. }
  32. sort(pre, pre + n + , cmp);
  33. for (int i = ; i < k; i++)
  34. {
  35. int t;
  36. scanf("%d", &t);
  37. int Min = INF;
  38. int l = , r = ;
  39. int ans, ansl, ansr;
  40. while (r <=n)
  41. {
  42. int sub = pre[r].sum - pre[l].sum;
  43. while (abs(sub - t) < Min)
  44. {
  45. Min = abs(sub - t);
  46. ansl= min(pre[l].id, pre[r].id) + ;
  47. ansr = max(pre[l].id, pre[r].id);
  48. ans = sub;
  49. }
  50. if (sub < t)
  51. r++;
  52. else if (sub > t) l++;
  53. else break;
  54. if (l == r) r++;
  55. }
  56. printf("%d %d %d\n", ans, ansl, ansr);
  57. }
  58. }
  59. return ;
  60. }

poj 2739

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

思路:

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

用尺取法的代码:

  1. for (;;) {
  2. while (r < size&&sum < n)
  3. {
  4. sum += primes[r++];
  5. }
  6. if (sum < n) break;
  7. else if (sum == n) result++;
  8. sum -= primes[l++];
  9. }

解决问题的代码:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <algorithm>
  4. #include <math.h>
  5. #include <cstring>
  6. #include <vector>
  7. #include <queue>
  8. using namespace std;
  9. #define maxn 10000+16
  10. vector<int> primes;
  11. vector<bool> is_prime;
  12. void init_prime()
  13. {
  14. is_prime = vector<bool>(maxn + , true);
  15. is_prime[] = is_prime[] = false;
  16. for (int i = ; i < maxn; i++)
  17. {
  18. if (is_prime[i])
  19. {
  20. primes.push_back(i);
  21. for (int j = i * ; j < maxn; j += i)
  22. {
  23. is_prime[j] = false;
  24. }
  25. }
  26. }
  27. }
  28. int main()
  29. {
  30. int n;
  31. init_prime();
  32. int size = primes.size();
  33. while (cin >> n && n)
  34. {
  35. int result = , sum = ;
  36. int l = ,r = ;
  37. for (;;) {
  38. while (r < size&&sum < n)
  39. {
  40. sum += primes[r++];
  41. }
  42. if (sum < n) break;
  43. else if (sum == n) result++;
  44. sum -= primes[l++];
  45. }
  46. printf("%d\n", result);
  47. }
  48. return ;
  49. }

poj 2100

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

解决问题的思路:

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

用尺取法的代码:

  1. for (;;)
  2. {
  3. while (sum < n)
  4. {
  5. sq = r * r;
  6. sum += sq;
  7. r++;
  8. }
  9. if (sq > n) break;
  10. else if (sum == n) ans.push_back(make_pair(l, r));
  11. sum -= l * l;
  12. l++;
  13. }

解决问题的代码:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <algorithm>
  4. #include <math.h>
  5. #include <cstring>
  6. #include <vector>
  7. #include <queue>
  8. using namespace std;
  9.  
  10. typedef long long ll;
  11. vector<pair<ll, ll>> ans;
  12. void solve(ll n)
  13. {
  14. ll l = , r = , sum = , sq;
  15. for (;;)
  16. {
  17. while (sum < n)
  18. {
  19. sq = r * r;
  20. sum += sq;
  21. r++;
  22. }
  23. if (sq > n) break;
  24. else if (sum == n) ans.push_back(make_pair(l, r));
  25. sum -= l * l;
  26. l++;
  27. }
  28. ll size = ans.size();
  29. printf("%lld\n", size);
  30. for (ll i = ; i < size; i++)
  31. {
  32. ll ansr = ans[i].second;
  33. ll ansl = ans[i].first;
  34. printf("%lld",ansr-ansl);
  35. for (ll j=ansl;j<ansr;j++)
  36. printf(" %lld", j);
  37. printf("\n");
  38. }
  39. }
  40.  
  41. int main()
  42. {
  43. ll n;
  44. while (scanf("%lld", &n) != EOF)
  45. {
  46. if (n == ) break;
  47. solve(n);
  48. }
  49. return ;
  50. }

尺取法 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. Android's Media

    MediaService.Main #include <sys/types.h> #include <unistd.h> #include <grp.h> #inc ...

  2. 部分易被忽视的css3属性

    1.-webkit-tap-highlight-color 移动端页面点击按钮时会发现按钮上会出现一块阴影,设置-webkit-tap-highlight-color:rgba(0,0,0,0);就可 ...

  3. open ssh 常用的东西

    清除已经存在的但是不同设备的连接信息 ssh-keygen -f "/users/he/.ssh/known_hosts" -R 192.168.1.118 无密码登录openss ...

  4. hibernate 模拟实现和What is and Why O/R Mapping

    What is and Why O/R Mapping What is : 用面向对象的方式调用api,类库帮我们翻译成面向关系的方式. Why: 1.JDBC操作数据库很繁琐2.Sql 语句编写并不 ...

  5. java之Socket传递图片

    客户端: package client; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import ...

  6. Eclipse下JRebel的安装和基本使用

    JRebel有什么用? 做Java Web开发,一个很头疼的事情是,修改了一个类以后,Tomcat必须重新启动. 工程规模小还好说,如果规模大了,重启一次动不动就是一分多钟.那么频繁重启就会导致大量的 ...

  7. K星异客

    http://baike.baidu.com/view/222058.htm 这部改编自基恩·布汝尔1995年出版的同名小说的电影在当年的十月档票房榜上称冠.本来这部电影的外星人主人公属意于威尔.史密 ...

  8. Python基础学习之语句和语法

    语句和语法 python语句中有一些基本规则和特殊字符: 井号键“#”表示之后的字符为python注释: 三引号(‘‘‘ ’’’)可以多行注释 换行“\n”是标准的行分隔符(通常一个语句一行): 反斜 ...

  9. JavaScript 常用的Math对象

    Math.ceil(x); //返回x向上取整后的整数值. Math.floor(x); //返回x向下取整后的整数值.. Math.round(x); //返回四舍五入后的整数. Math.abs( ...

  10. COGS 2091. Asm.Def的打击序列

    ★★★   输入文件:asm_lis.in   输出文件:asm_lis.out   简单对比时间限制:4 s   内存限制:256 MB [题目描述] 白色圆柱形的“蓝翔”号在虚空中逐渐变大,一声沉 ...