Codeforces Round #271 (Div. 2) --B Worms (二分)

来源:互联网 发布:mac子弹头rebel 编辑:程序博客网 时间:2024/05/21 08:05

题目链接:http://codeforces.com/contest/474/problem/B


B. Worms
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

It is lunch time for Mole. His friend, Marmot, prepared him a nice game for lunch.

Marmot brought Mole n ordered piles of worms such that i-th pile contains ai worms. He labeled all these worms with consecutive integers: worms in first pile are labeled with numbers 1 to a1, worms in second pile are labeled with numbers a1 + 1 to a1 + a2 and so on. See the example for a better understanding.

Mole can't eat all the worms (Marmot brought a lot) and, as we all know, Mole is blind, so Marmot tells him the labels of the best juicy worms. Marmot will only give Mole a worm if Mole says correctly in which pile this worm is contained.

Poor Mole asks for your help. For all juicy worms said by Marmot, tell Mole the correct answers.

Input

The first line contains a single integer n (1 ≤ n ≤ 105), the number of piles.

The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 103a1 + a2 + ... + an ≤ 106), where ai is the number of worms in the i-th pile.

The third line contains single integer m (1 ≤ m ≤ 105), the number of juicy worms said by Marmot.

The fourth line contains m integers q1, q2, ..., qm (1 ≤ qi ≤ a1 + a2 + ... + an), the labels of the juicy worms.

Output

Print m lines to the standard output. The i-th line should contain an integer, representing the number of the pile where the worm labeled with the number qi is.

Sample test(s)
input
52 7 3 4 931 25 11
output
153
Note

For the sample input:

  • The worms with labels from [12] are in the first pile.
  • The worms with labels from [39] are in the second pile.
  • The worms with labels from [1012] are in the third pile.
  • The worms with labels from [1316] are in the fourth pile.
  • The worms with labels from [1725] are in the fifth pile.




大致题意:就简化叙述一下,worms这个词确实没看懂。。。但是还是不影响我们理解题意的,就是给你好多小序列的长度,并且小序列依次编号为1~n,我们现在要把这么多小序列按给出的顺序直接合成一个序列,每个小序列的实际位置就是当前大序列的下标,说白了,就是把这么多小序列依次排开,然后出了第一个序列的下标不变以外,后面的下标都依次累加,得到一个新的序列。这是候给你一个数,问你它属于原来的那个小段,并输出原来小段的编号。



解题思路1:这题开始输入的时候就把原数组处理一下,加上前一个的值,就相当于用每一个元素把每一段的左端点存了下来,然后直接用了lower_bound(),直接查找某个数的位置。这题的思想是二分查找,但是懒得写二分,就用lower_bound()直接搞了。

                  lower_bound()的用法:假如在大小为n的数组A(前提是数组A必须有序)中查找第一个比K小的数的位置,就可以这样写  pos = lower_bound( A, A+n, k) - A ;注意,函数返回的是第一个比K小的数的地址。同样,upper_bound()函数返回的是第一个比K大的数的地址。  一定要注意前提:数组必须有序。



AC代码:

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;#define INF 0x7fffffffint a[100005];int main(){    #ifdef sxk        freopen("in.txt","r",stdin);    #endif    int n, m, k;    while(scanf("%d",&n)!=EOF)    {        a[0] = 0;        for(int i=1; i<=n; i++){            scanf("%d", &a[i]);            a[i] += a[i-1];        }        scanf("%d", &m);        for(int i=0; i<m; i++){            scanf("%d", &k);            printf("%d\n", lower_bound(a, a+n, k) - a);        }    }    return 0;}



解题思路2:打完比赛,一刷排名,tourist竟然也来div2了,又一次感慨跟大神的差距,真不是一个世界的,31分钟AK,唉,啥时候能一小时AK就好了。。。

看了tourist的思路,只需要开一个数组,每一段内存的值就是当前下标所在的段数,所以查找的时候O(1)就搞定了,太佩服了,好腻害!!!

详见代码




AC代码:

#include <cstring>#include <vector>#include <list>#include <map>#include <set>#include <deque>#include <stack>#include <bitset>#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <sstream>#include <iostream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstdlib>#include <ctime>#include <memory.h>#include <cassert>using namespace std;int b[2000010];int main() {  int n;  scanf("%d", &n);  int m = 0;  for (int i = 0; i < n; i++) {    int foo;    scanf("%d", &foo);    for (int j = 0; j < foo; j++) {      b[++m] = i + 1;    }  }  int tt;  scanf("%d", &tt);  while (tt--) {    int foo;    scanf("%d", &foo);    printf("%d\n", b[foo]);  }  return 0;}



0 0
原创粉丝点击