#bzoj3375#膈膜(水题来着,但小问题频发,一点感受心得)

来源:互联网 发布:edusoho源码下载 编辑:程序博客网 时间:2024/06/06 15:41

【geng4512膜你题1】隔膜

时间限制: 1 Sec  内存限制: 256 MB

【问题描述】

      steam夏季大促销来啦,azui大爷最近在steam上买了1mol的游戏。一天他突然发现了一个搬砖的游戏:

      有N种砖头,每种砖头有mi个,每一个的价值为di。每一个单位时间你必须搬一块砖,到无砖可搬为止。有一个得分系数F,初始时为1。搬一块砖的得分为当时的得分系数F*di。有T个时间分割点。每过一个时间分割点,F会自己加一。

      例如在时间pi的得分为i*di,而在时间pi+1的得分为(i+1)*di。

azui大爷觉得这个游戏too simple,不想去玩,于是让你去帮他上分,希望你能告诉他每局游戏的最大的分。

你一定知道这么简单的题目怎么做,快帮帮azui大爷吧。

 

【输入格式】

      第一行一个数N。

      接下来的N行,每行两个数,表示mi和di。

      之后的一行一个数T。

      接下来的一行T个数,pi。

【样例输入1】

2

3 8

5 10

1

20

【样例输出1】

74

【样例输入2】

1

1 1000

1

1

 

【样例输出2】

1000

 

【数据范围】

对于30%的数据,

1<=N<=10

对于100%的数据,

      1<=N<=100

      1<=mi<=109

      0<=di<=1000

      1<=t<=100

      1<=p2<p3<…<pt<=10^12


某耿姓前辈出的模拟题的第一题,他的原意是送分的贪心大水题,但我在实现上还是有很多乱七八糟的问题,

导致这题成为了对于我的一个很好的问题,来看看当时是干了些什么神奇的事情。


思路很简单,按价值排序后循环模拟就行。


第一个问题是清醒,自己对Time的定义一直都不是很明确

(到底是已经完成了Time个,现在应该到Time+1个,还是现在是第Time个)

然后在写代码的时候后面+1-1就开始乱打,处于混乱,

但样例实在太水,也怪我自己构造的数据太少太差,所以没有第一时间发现问题,

就跑去写第二题了。


第二个问题是循环的退出条件(个人觉得这个在循环模拟中很重要但很容易随便写一个就晃过去了)

这题就是最后循环退出的条件不对才错了的,

那种严格还是非严格的不等号其实挺要命的,

最好写的时候想一下最后一次进入然后退出循环的过程。


第三个问题是清晰的代码布局(个人觉得这是考试不昏,且代码调得出的重要问题之一)

哪个部分该干什么,哪个部分只处理什么都应该十分清楚,

有必要的时候加注释辅助一下情况分析讨论。


嗯,这么一道题被我啰嗦得也够多了,还有些小问题就先不一一列举了,考着错真的太痛了。

Code:

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std; typedef long long LL; const int Max = 105; struct node{    int m, d;    bool operator < (const node & X)const{        return d < X.d;     }}Caol[Max]; LL All, Ans;int N, T;LL P[Max]; void getint(int & num){    char c; int flg = 1;    num = 0;    while((c = getchar()) < '0' || c > '9')   if(c == '-')    flg = -1;    while(c >= '0' && c <= '9'){  num = num * 10 + c - 48;    c = getchar();}    num *= flg;} void getLL(LL & num){    char c; int flg = 1;    num = 0LL;    while((c = getchar()) < '0' || c > '9')   if(c == '-')    flg = -1;    while(c >= '0' && c <= '9'){  num = num * 10 + c - 48;    c = getchar();}    num *= flg;} int main(){    //freopen("game.in", "r", stdin);    //freopen("game.out", "w", stdout);    getint(N);    for(int i = 1; i <= N; ++ i)        getint(Caol[i].m), getint(Caol[i].d), All += Caol[i].m;    sort(Caol + 1, Caol + 1 + N);    getint(T);    for(int i = 1; i <= T; ++ i)        getLL(P[i]);    P[T + 1] = 10000000000000LL;    int p = 1, Sco = 1, i = 1;    for(LL Time = 0LL; Time < All; ){        if(P[p] - Time >= Caol[i].m){            Time += Caol[i].m;            Ans += (LL)Caol[i].m * Caol[i].d * Sco;            ++ i;        }        else {            Ans += (LL)(P[p] - Time) * Caol[i].d * Sco;            Caol[i].m -= P[p] - Time;            Time = P[p];        }        if(Time + 1 > P[p])  ++ Sco, ++ p;    }    printf("%lld\n", Ans);    return 0;}






原创粉丝点击