CSDN 编程竞赛三十九期:比赛详情 (csdn.net)
最近小艺酱渐渐变成了一个圆滑的形状球,小艺酱开始变得喜欢上球!小艺酱得到n个同心圆。小艺酱对着n个同心圆进行染色,相邻的圆范围内不能有相同的颜色,相隔一层的圆颜色相同。小艺酱想知道两种颜色中最外层圆的那种颜色总共染了多少面积?
#include
#include
int main () {
double resu1t = 0;
int n;
scanf ("%d", &n);
double data [n];
for (int i = 0; i < n; i++) scanf ("%lf", &data [i]);
std::sort (data, data + n);
for (int i = n - 1; i > -1; i -= 2) {
int i_1 = i - 1;
resu1t += 圆周率 * (data [i] * data [i] - data [i_1] * data [i_1]);
}
return 0;
}
圆的面积为Pi * (r ^ 2),同心圆的面积为Pi * (R ^ 2 - r ^ 2)。其中,R为大圆半径,r为小圆半径。
注意,圆周率需要给到足够的长度,否则计算出的结果精度不够千分位,会卡一部分测试点。
小张和他的M个朋友来到了一个十分神奇的地方,在这里有N个柱子,每个柱子有两个属性:高度(Height)、位置(Pos)。题目保证同一个位置不会有多个柱子。请你计算出每个小张的朋友能清晰看到的最远一个柱子的位置,如果那个朋友一个柱子都没有清晰看到,请输出-1。
1、当一个柱子b在另一个不比他低的柱子a的后面时(P[b] > P[a] && H[b] <= H[a]),这个柱子会被遮挡住,也就不再能够被清晰地看到。
2、小张和他的朋友们在位置0休息时,发现似乎朋友们能清晰看到的柱子数量并不相同。在他反复思考后,他认为这可能是近视度数导致的,于是他询问了每一个朋友的近视度数A。为了方便计算,我们认为对于每个朋友来说,对每一个柱子,如果有P [i] > A,那么第 i 个柱子无法被清晰地看见。
此题由CSDN用户a23333a提供。
这道题目分为两步求解:
鉴于总是有人恶意抄袭博主文章,并且竞赛时也可能遇到之前出现过的题目,博主会尽量将思路讲解得全面一些,并减少代码含量。
1、第一步,不考虑朋友的近视度数,单独判断柱子是否被遮挡。
2、第二步,单独判断每个朋友观察柱子的具体情况,找出其能够观察到的最远柱子位置。
求解时,需要考虑如下要点:
1、创建一个柱子结构,输入数据之后,将柱子按照位置从近到远的顺序进行排序。
#include
#include
struct node {
int height;
int pos;
bool disvisible;
};
int cmp (node a, node b) {
return a.pos < b.pos;
}
int main () {
scanf ("%d %d", &m, &n);
node data [n];
for (int i = 0; i < n; i++) scanf ("%d", &data [i].height);
for (int i = 0; i < n; i++) scanf ("%d", &data [i].pos);
std::sort (data, data + n, cmp);
return 0;
}
2、更新柱子的可视情况,即结构体中的disvisible属性。这项属性的默认值为false,如果柱子不可视,将其置为true。
更新时,需要特别注意题目中对遮挡判定条件的有关描述。
这段描述可以简化为,如果当前柱子在一个柱子的后面,并且高度未超过前面的柱子,那么它就会被遮挡。也可以理解为:前面较高的的柱子,会挡住后面的柱子。特别是,如果刚开始遇到的柱子九非常高,那么它有可能把后面大部分甚至全部的柱子都挡住。
因此,更新可视情况时,需要动态维护最高柱子的高度。默认第一个柱子就是最高的柱子,并且它肯定不会被挡住,只需要从第二个柱子开始更新即可。
更新时,先检查当前正在判断的柱子高度有没有超过之前记录的较高的柱子,如果更高,更新最大高度。这时,当前这个柱子肯定可视,因为它比前面最高的柱子还要高。否则,这个柱子的高度没有超过前面的柱子,那么它会被遮挡!这时,需要将disvisible置为true。
博主在竞赛时特别留意了一下这一步,并且赛后发现很多人这道题目只通过了90%的测试点。其中原因之一,很可能就是这个部分的写法导致的。
更新完成后,将所有可视的柱子加入到一个列表中,以备后续计算使用。
3、使用循环读入每个朋友的近视情况。当遇到新的朋友时,根据其近视情况,判断其能看到的最远柱子位置。
由于柱子已经按位置排好序,因此,上一步计算出来的可视柱子,位置仍然是有序的。这一步可以直接将这部分数据拿来使用。
注意,本题中定义的近视度数满足这样的规律:近视情况越严重,能看到的位置越近,即近视度数数值越小。当柱子位置超过近视度数时,柱子便无法被看到。这与现实中的标准有部分差异,需要充分理解,才能解决这道题目。
柱子的起始位置大于零,意味着,如果近视度数也为零,那么对于这位朋友而言,任何柱子都无法被看到。题目规定如果任何柱子都无法被看到,输出-1。我们可以巧妙地利用哨兵来处理这个情况。上一步已经记录了可视柱子的位置,只需要将-1插入到这个列表的首部即可。
对于每一位朋友,可以默认其能看到的柱子是最远的那个可视柱子(假设有n个可视柱子,那么初始最远下标置为n)。之后,使用循环从前到后扫描每个柱子,判断其能否被看到。注意,由于加入了哨兵,需要跨过其进行扫描,因此起始下标不是零。对于每个柱子,如果其位置大于近视度数,那么更新能看到的最远柱子的下标,并跳出循环。
题目要求输出最远柱子的位置,由于柱子位置列表下标从零开始,我们只需输出记录的最远柱子下标-1的那个数组成员即可。
例如,能看到全部的柱子,位置为 visible [n - 1]。
若只能看到一个柱子,则循环至第二个柱子时就卡到判定条件,并跳出循环,这时输出位置为 visible [2 - 1]。
如果任何柱子也看不到,位置为 visible [1 - 1],即 visible [0] == -1。
已知n天后的股票行情,现在已有的本金是m,规定只能入手一次股票和抛售一次股票。最大收益是多少(含本金)?
#include
int main () {
int n, m;
scanf ("%d %d", &n, &m);
int price [n], award = 0;
for (int i = 0; i < n; i++) scanf ("%d", &price [i]);
for (int i = 0; i < n; i++) {
// calc awardNow;
for (int j = i + 1; j < n; j++) {
award = max (award, awardNow);
}
}
return 0;
}
计算每一天的收益(卖出收益 - 购入成本),当收益超过历史最大收益时,更新历史收益。
最后,输出本金 + 历史最大收益即可。
P老师需要去商店买n支铅笔作为小朋友们参加编程比赛的礼物。她发现商店一共有三种包装的铅笔,不同包装内的铅笔数量有可能不同,价格也有可能不同。为了公平起见,P老师决定只买同一种包装的铅笔。商店不允许将铅笔的包装拆开,因此P老师可能需要购买超过n支铅笔才够给小朋友们发礼物。现在P老师想知道,在商店每种包装的数量都足够的情况下,要买够至少n支铅笔最少需要花费多少钱。
#include
const int size = 3;
int main () {
int resu1t = 0;
int n;
scanf ("%d", &n);
int count [size], cost [size], price [size];
for (int i = 0; i < size; i++) {
scanf ("%d %d", &count [i], &cost [i]);
// calc price [i];
if (price [i] < price [resu1t]) resu1t = i;
}
return 0;
}
题目规定只能买一种铅笔,而不能混搭。因此,可以使用循环来计算买每种铅笔花费的价格。
当价格比历史价格更低时,则更新历史最低价格对应的铅笔类型。
完成对所有铅笔种类的计算之后,输出最低价格即可。