ACM-sdut3108赏赏赏

来源:互联网 发布:爱因斯坦 大学 知乎 编辑:程序博客网 时间:2024/06/05 04:30

题目描述

B国大举进犯,A国根据地利设下埋伏获得全胜,战后A国王论功行赏,现在问题来了。
现在我们将问题简化,已知B国一共来了M个士兵,每个士兵的生命值为Hi,A国设置了N个据点,当士兵经过第j个据点时,生命值减少Wj,当士兵的生命值小于等于0时就会被当前这个据点杀死。由于地形原因士兵必须依次经过据点1,据点2,据点3. . . . . .据点N。
现在A国王想知道前M个据点的杀敌数为多少。

输入

多组输入。
对于每组数据,首先输入两个整数N,M(1 <= N <= 100000,1 <= M<= min(N, 10000))。
接下来的M行,每行一个整数Hi,代表第i个士兵的初始生命值。(1 <= Hi <= 10000000)
接下来的N行,每行一个整数Wj,代表第j个据点的攻击力。(0 <= Wi <= 10000)

输出

对于每组数据。
输出M行,每行一个整数代表第j个据点的杀敌数。

示例输入

3 3123111

示例输出

11

1

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int hi[1111111],wi[1111111],over[1111111];int main(){    int n,m,i,j;    while(scanf("%d%d",&n,&m)!=EOF)    {for(i=0;i<m;i++)    over[i]=0;        for(i=0;i<m;i++)            scanf("%d",&hi[i]);            sort(hi,hi+m);        for(i=0;i<n;i++)        {            scanf("%d",&wi[i]);            wi[i]=(i==0?wi[i]:wi[i-1]+wi[i]);        }        for(i=0,j=0;i<m&&j<m;)        {if(wi[i]>=hi[j])  {over[i]++;/*printf("%d %d\n",over[i],i);*/ j++;}        else i++;        }        for(i=0;i<m;i++) printf("%d\n",over[i]);    }return 0;}

刚开始题意理解错了,等到理解之后发现累加比较麻烦,正巧一博客有此题,第18行的三目运算法用的很巧妙。

士兵生命值需要排序,但是感觉题目没提及。

另刚开始用memset重置over,发现对于比较大的数组很浪费时间和内存,反而用for循环更好。

对这道题来用for节约了大概100ms时间和4000K左右的内存。


还有一种更简洁的办法,就是用二分查找的原理,通过lower_bound()这个函数来查找士兵的生命值第一次小于等于据点攻击力的位置,从而使该据点的杀敌数加一。
#include <iostream>     #include <cstring>     #include <algorithm>         using namespace std;         int h[1000000],w[1000000],cont[1000000];         int main()     {         ios::sync_with_stdio(false);         int n,m,i;         while(cin>>n>>m)         {             memset(cont,0,sizeof(cont));             for(i=0;i<m;i++)                 cin>>h[i];             for(i=0;i<n;i++)             {                 cin>>w[i];                 if(i!=0)                     w[i]+=w[i-1];             }             for(i=0;i<m;i++)             {                 int x=lower_bound(w,w+n,h[i])-w;                 cont[x]++;             }             for(i=0;i<m;i++)                 cout<<cont[i]<<endl;         }         return 0;     }   
思路来自SDUT。

0 0
原创粉丝点击