码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 526 E Transmitting Levels 滑窗(two points) + 枚举

时间:2015-04-05 21:51:11      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:

题意:给你一个环形数组,让你求将这个数组分成 每段和 <= k 的最小段数。

解题思路:滑窗求的以 i结尾的 最长段长度,然后枚举最小的那个段长度中的值为终点搜索(因为必定有一个分割点在 最小段长上)

解题代码:

技术分享
  1 // File Name: e.cpp
  2 // Author: darkdream
  3 // Created Time: 2015年04月05日 星期日 14时55分31秒
  4 
  5 #include<vector>
  6 #include<list>
  7 #include<map>
  8 #include<set>
  9 #include<deque>
 10 #include<stack>
 11 #include<bitset>
 12 #include<algorithm>
 13 #include<functional>
 14 #include<numeric>
 15 #include<utility>
 16 #include<sstream>
 17 #include<iostream>
 18 #include<iomanip>
 19 #include<cstdio>
 20 #include<cmath>
 21 #include<cstdlib>
 22 #include<cstring>
 23 #include<ctime>
 24 #define LL long long
 25 #define maxn 3000005
 26 using namespace std;
 27 int n , q; 
 28 int a[maxn];
 29 int from[maxn];
 30 int tans ;
 31 int pp;
 32 int read_int() {
 33     char ch = getchar();
 34     while (!isdigit(ch)) {
 35         ch = getchar();
 36     }
 37     int ret = 0;
 38     while (isdigit(ch)) {
 39         ret = ret * 10 + ch - 0;
 40         ch = getchar();
 41     }
 42     return ret;
 43 }
 44 int main(){
 45 //    freopen("input","r",stdin);
 46     scanf("%d %d",&n,&q);
 47     for(int i = 1;i <= n;i ++)
 48     {    
 49         a[i] = read_int();
 50         a[i+n] = a[i];
 51     }
 52     while(q--)
 53     {
 54        LL lim;
 55        cin >>lim;
 56        LL tsum =0 ; 
 57        int ans = 1e9 ;
 58        int milr = 1e9 ; 
 59        int l ,r ; 
 60        l = 2*n;
 61        r = 2*n-1;
 62        int j = 1; 
 63        for(int i = 1;i <= 2* n ;++i)
 64        {
 65            tsum += a[i];
 66            while(tsum > lim )
 67            {
 68                tsum -= a[j];
 69                j ++;
 70            }
 71            from[i] = j-1;
 72            if(i - (j-1)< milr && i >= n)
 73            {
 74               l = j-1;
 75               r = i ; 
 76               milr = (i-(j-1));
 77            }
 78        }
 79        for(int i = n+1;i <= 2* n;i ++)
 80             from[i+n] = from[i]+n;
 81        if(l < n)
 82        {
 83          l += n ; 
 84          r += n ; 
 85        }
 86        //printf("%d %d\n",l,r);
 87        for(pp = l;pp <= r;pp++)
 88        {
 89            tans = 0 ; 
 90            for(int i = pp ;i >= 0;i = from[i])
 91            {
 92                tans ++ ; 
 93                if(i <= pp -n)
 94                {
 95                    break;
 96                }
 97            }
 98            ans = min(ans,tans-1);
 99        }
100       printf("%d\n",ans);
101     
102     }
103     
104 
105 return 0;
106 }
View Code

 

Codeforces 526 E Transmitting Levels 滑窗(two points) + 枚举

标签:

原文地址:http://www.cnblogs.com/zyue/p/4394793.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!