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

xiaoxiao2021-02-28  71

【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; }

转载请注明原文地址: https://www.6miu.com/read-73484.html

最新回复(0)