ACM 二分 Aggressive cows & 尺取 Subsequence

た 入场券 2022-06-12 08:46 270阅读 0赞

滴,集训第三天打卡。

今天是堆,二分和尺取,不过我好像没做到用堆的…

二分的套路是:

  1. while(f<=l)//二分
  2. {
  3. mid=(f+l)/2;
  4. if(hs(mid))//判断中间值是否满足条件
  5. f=mid+1;
  6. else
  7. l=mid-1;
  8. }

尺取法:尺取法通常是对数组保存一对下标,即所选取的区间的左右端点,然后根据实际情况不断地推进区间左右端点以得出答案。

  1. int l = 0,w= 0,sum = 0,ans=n+1;
  2. while(1)
  3. {
  4. while(w < n && sum<s)
  5. {//从前面开始
  6. sum+=a[w];
  7. w++;
  8. }
  9. if(sum < s)
  10. {//条件不满足了;
  11. break;
  12. }
  13. min = w-l;
  14. if(min > ans)
  15. min = ans;
  16. ans = min;//ans就是最小长度
  17. sum -= a[l++];//尺取法的前进;
  18. }

POJ 2456 Aggressive cows(二分)

20170720102138369

题目大意FJ 有一个很长的谷仓 ,然后里面有 N 棚, N 个棚在一条直线上,第 i 个棚的位置为 xi。然后他有 c 只牛,为了防止牛相互攻击,则要找出最大的两只牛之间距离,前提是这 c 只牛都必须能放下。

解题思路:排序谷仓,从第一个出发(第一个肯定选),查找间距为n的是否存在,如果到末尾都满足的话,说明n成立,查找最大的n即可。(我的是在函数里sb里查找是否满足的)

  1. #include <stdio.h>
  2. #include <algorithm>
  3. using namespace std;
  4. int a[100005];
  5. int n,m,i,j,f,l,mid;
  6. bool sb(int mm)
  7. {
  8. int i,s=1,k=0;
  9. for(i=1;i<n;i++)
  10. {
  11. if(mm+a[k]<=a[i])
  12. {
  13. k=i;
  14. s++;
  15. }
  16. if(s==m)
  17. break;
  18. }
  19. if(s<m)return false;
  20. return true;
  21. }
  22. int main()
  23. {
  24. scanf("%d%d",&n,&m);
  25. for(i=0;i<n;i++)
  26. scanf("%d",&a[i]);
  27. sort(a,a+n);
  28. f=1,l=a[n-1]-a[0];
  29. while(f<=l)//二分
  30. {
  31. mid=(f+l)/2;
  32. if(sb(mid))
  33. f=mid+1;
  34. else
  35. l=mid-1;
  36. }
  37. printf("%d\n",l);
  38. }

POJ 3061 Subsequence(尺取法)

20170720104746925

题目大意:给定长度n的数列整数,以及整数s,求出总和不小于S的连续子序列的长度的最小值。

解题思路:直接用尺取法呀…

  1. #include <stdio.h>
  2. int a[100005];
  3. int main()
  4. {
  5. long long t,n,s,i,k,sum,f,l,ss,num,nn;
  6. scanf("%lld",&t);
  7. while(t--)
  8. {
  9. k=0;sum=0;
  10. scanf("%lld%lld",&n,&s);
  11. for(i=0;i<n;i++)
  12. {
  13. scanf("%lld",&a[i]);
  14. if(a[i]>=s)
  15. k=1;
  16. sum+=a[i];
  17. }
  18. if(k==1)//有单独一个存在可以满足s,则1为最小值
  19. printf("1\n");
  20. else if(sum<s)//如果总合都不够s,则肯定不存在
  21. printf("0\n");
  22. else
  23. {
  24. f=0;l=0;num=n+1;nn=0,ss=0;
  25. while(f<=l&&l<n)//尺取
  26. {
  27. while(ss<s&&l<n)
  28. {
  29. ss+=a[l];
  30. nn++;l++;
  31. }
  32. while(ss>=s&&f<n)
  33. {
  34. if(nn<num)
  35. num=nn;
  36. ss-=a[f];
  37. f++;
  38. nn--;
  39. }
  40. }
  41. if(num!=n+1)
  42. printf("%lld\n",num);
  43. else
  44. printf("0\n");
  45. }
  46. }
  47. }

发表评论

表情:
评论列表 (有 0 条评论,270人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Pie————二分+练习

    给你n个蛋糕的半径,你有m个朋友,所以总共有m+1个人,现在要分蛋糕,要求每个人分到的大小都是一样的,且每个人的蛋糕都是从一块上切割下来的(不能是2个不同的蛋糕拼起来的),现在