zoukankan      html  css  js  c++  java
  • 蓝桥杯ALGO1003

    问题描述
      JiaoShou在爱琳大陆的旅行完毕,即将回家,为了纪念这次旅行,他决定带回一些礼物给好朋友。
      在走出了怪物森林以后,JiaoShou看到了排成一排的N个石子。
      这些石子很漂亮,JiaoShou决定以此为礼物。
      但是这N个石子被施加了一种特殊的魔法。
      如果要取走石子,必须按照以下的规则去取。
      每次必须取连续的2*K个石子,并且满足前K个石子的重量和小于等于S,后K个石子的重量和小于等于S。
      由于时间紧迫,Jiaoshou只能取一次。
      现在JiaoShou找到了聪明的你,问他最多可以带走多少个石子
     
    样列输入
      8 3
      1 1 1 1 1 1 1 1
    样列输出
      6
    样列解释
      任意选择连续的6个1即可。
     
    思路:二分答案。每次二分一个答案,如果当前的答案能满足存在一个序列S1+...+Sk<=s并且Sk+1+...+S2k<=s,就继续从mid后面找,如果不满足就从mid前面找。把满足的结果保存下来,最后保存的结果就是要求的结果。时间复杂度为n(logn),能跑完。
    AC代码:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int Max=1000003;
     5 const int mod=10007;
     6 ll sum[Max];
     7 int n;
     8 ll s;
     9 int kk(int k)
    10 {
    11     for(int i=k; i<=n&&i+k<=n; i++)
    12         if(sum[i]-sum[i-k]<=s&&sum[i+k]-sum[i]<=s)return 1;//存在序列i~i+2*k-1满足条件
    13     return 0;
    14 }
    15 int main()
    16 {
    17 
    18     cin>>n>>s;
    19     for(int i=1; i<=n; i++)
    20     {
    21         ll a;
    22         cin>>a;
    23         sum[i]=sum[i-1]+a;
    24     }
    25     int k=0;
    26     int l,r;
    27     l=1;
    28     r=n/2;//不能超过序列的一半
    29     while(l<=r)
    30     {
    31         int mid=(l+r)/2;
    32         if(kk(mid))
    33         {
    34             l=mid+1;
    35             k=mid;
    36         }
    37         else r=mid-1;
    38     }
    39     cout<<k*2<<endl;
    40 }
    View Code
  • 相关阅读:
    第三周学习笔记
    Python简易购物车程序
    记录回忆,谢谢你,别忘了我。
    学习第二周
    入园3个月首次写个帖
    Linux系统mysql多实例主从
    linux系统开机流程和启动nginx
    linux系统rsync命令
    linux监控进程状态命令自定义rpm包及kill命令
    linux搭建yum仓库
  • 原文地址:https://www.cnblogs.com/zxz666/p/15785823.html
Copyright © 2011-2022 走看看