您的位置:首页 > 其它

【ZOJ月赛】【二分查找】【A.Edward's Cola Plan】

2013-01-22 21:21 246 查看
【题目来源】http://acm.zju.edu.cn/onlinejudge/showContestProblem.do?problemId=4929

【个人体会】这个题目是我在4小时50多分钟最后AC的,因为我一看这个题目时限是3S就有点心虚,怕为了搞这个题目而忽略了“可能”存在的水题,最后连这个题目也没搞出来。不过后来看到这个题目过的人数就发现了原来这个题目才是水题。。。

【题目大意】唧唧歪歪半天,意思很简单。就是对于每个朋友,在Pi和Qi-M中选一个大的,然后求和。接着,给出T组询问,每次M的值都在变化,要求每组询问的和。

【题目解析】根据Qi-Pi的差值进行排序,对于每组M,求出它在排序后的数组中的位置(二分查找),然后对于这个位置以前的所有人都选Pi,对于这个位置以后的所有人都选Qi-M。另外,预处理出Pi和Qi的前缀和。

【代码如下】

#include <cstdio>
#include <algorithm>

using namespace std;

struct Cola
{
int p, q;
}A[100005];

int N, T, Sumq[100005], Sump[100005];

bool Cmp(const Cola &a, const Cola &b)
{
return ((a.q - a.p) < (b.q - b.p));
}

void Solve()
{
sort(A + 1, A + 1 + N, Cmp);
for (int i = 1; i <= N; i ++)
{
Sump[i] = Sump[i - 1] + A[i].p;
Sumq[i] = Sumq[i - 1] + A[i].q;
}
for (int i = 1, M; i <= T; ++i)
{
scanf("%d", &M);
int l = 1, r = N + 1, ans = -1;
while (l <= r)
{
int m = (l + r) / 2;
if (A[m].q - A[m].p < M) l = m + 1;
else
{
ans = m; r = m - 1;
}
}
if (ans == -1) printf("%d\n", Sump
);
else printf("%d\n", Sump[ans - 1] + Sumq
- Sumq[ans - 1] - M * (N - ans + 1));
}
}

void Init()
{
for (int i = 1; i <= N; ++i) scanf("%d%d", &A[i].p, &A[i].q);
}

int main()
{
while (scanf("%d%d", &N, &T) != EOF)
{
Init();
Solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: