昨天偶然在优快云的消息上看到了有一场比赛,就想也没想参加了。以前从来没有参加过这样的比赛这次就当为机试积累经验,同时这篇博客也是我在优快云上发布的第一篇博客,介绍一下我在比赛过程中的心路历程。
判断题
题目描述
使用n位定点数编码方案,最多能够表示的数值个数为2ⁿ个。但是,这些数值中可以包括小数。
答案
正确
解释
隐约记得计组课上讲过的,定点数就是将一个数分为整数部分和小数部分,例如一个8位定点数,前四位表示整数,后四位表示小数,则 1100 1100
就表示:
8
+
4
+
1
2
+
1
4
=
12.75
8 + 4 + \dfrac{1}{2} + \dfrac{1}{4} = 12.75
8+4+21+41=12.75
能表示的数值有
2
n
2^n
2n 个也没毛病。
单选题
题目描述
在同时涉及极大和极小浮点数值的算法中,以下哪一种在需要保证可靠性和性能的平衡时不是需要采取的策略?
A、避免在一次运算中同时涉及极大的绝对值和极小的绝对值的数值
B、先粗调,再精调
C、为保证可靠性,必须精益求精而不能进行粗调
D、对进行计算的数值进行预处理,比如可以先对其取对数
答案
C一眼错
题目描述
使用IEEE754标准,可以准确地表示以下哪个数值?
A、1E310
B、-3.1415926535897932384626
C、0
D、以上都不对
答案
D,很多人纠结C,其实IEEE754标准里0有+0和-0,用过C语言的同学应该知道有时候浮点数计算会计算出-0,而这两个是不相等的。
填空题
题目描述
信息的动态范围和()是一对矛盾,根据不同的应用平衡二者的关系,是信息编码的艺术。
答案
精度
我的内心
好像是书上的,真的不会没办法(随手写上静态范围)
编程题
1、路灯亮度
题目描述
有一条长度为n米的街道,上面分布着一些亮度不等的路灯。每离开某盏路灯1米,该位置受该盏路灯影响的亮度就比该盏路灯的原始亮度减少1个单位,而某个特定位置的最终亮度则等于所有影响该位置的路灯亮度的最大值,而亮度的最小值为0。
思路讲解
首先想到了暴力,毫无技术含量的
n
2
n^2
n2 解法毫无悬念地超时了。于是我哭哭想如何优化,终于在考场上为自己的脑洞折服:使用动态规划!
但是有个问题啊,这个路灯是向前后两个方向扩散的,你算出一个地方的亮度怎么保证不受后面的路灯干扰啊?那我就——算两遍呗,如图所示,先把双向路灯拆成单向路灯:
之后对于两种情况分别进行动态规划,上图的递推表达式为:
d
p
1
[
i
]
=
{
a
[
1
]
,
i
=
1
max
(
a
[
i
]
,
s
[
i
−
1
]
−
1
)
,
1
<
i
≤
n
dp1[i] = \left\{ \begin{aligned} &a[1], &&i=1\\ &\max(a[i], s[i-1]-1), &&1<i\leq n \end{aligned} \right.
dp1[i]={a[1],max(a[i],s[i−1]−1),i=11<i≤n
下图则为:
d
p
2
[
i
]
=
{
a
[
n
]
,
i
=
n
max
(
a
[
i
]
,
s
[
i
+
1
]
−
1
)
,
1
≤
i
<
n
dp2[i] = \left\{ \begin{aligned} &a[n], &&i=n\\ &\max(a[i], s[i+1]-1), &&1\leq i < n \end{aligned} \right.
dp2[i]={a[n],max(a[i],s[i+1]−1),i=n1≤i<n
然后我们的答案就变成了:
d
p
[
i
]
=
max
(
d
p
1
[
i
]
,
d
p
2
[
i
]
)
,
1
≤
i
≤
n
dp[i]=\max(dp1[i], dp2[i]), 1\leq i\leq n
dp[i]=max(dp1[i],dp2[i]),1≤i≤n
代码展示
#include<stdio.h>
#define MAX 10000005
int dp1[MAX];
int dp2[MAX];
int lamp[MAX];
int max(int a, int b) {
return a > b ? a : b;
}
int main() {
int n, m;
int p, l;
int x;
scanf("%d%d", &n, &m);
for (int i = 0; i < m; i++) {
scanf("%d%d", &p, &l);
lamp[p] = l;
}
dp1[1] = lamp[1];
for (int i = 2; i <= n; i++) {
dp1[i] = max(dp1[i - 1] - 1, lamp[i]);
}
dp2[n] = lamp[n];
for (int i = n - 1; i >= 1; i--) {
dp2[i] = max(dp2[i + 1] - 1, lamp[i]);
}
while(~scanf("%d", &x)) {
printf("%d\n", max(dp1[x], dp2[x]));
}
return 0;
}
2、池塘水量
某地有n个池塘,编号为i的池塘最大容积为i(从1开始编号),一开始都没有水。每天的天气状况决定了所有水池同时的水量变化,如果某天下了容积为v的雨表示所有池塘都会增加容积v的水,当然池塘满了的话水就会溢出而流走,不会影响到次日以后。如果某天天气炎热而蒸发了容积为v的水表示所有池塘都会减少容积v的水,当然池塘最多把所有水蒸发干而变成容积为0,也不会影响到次日以后。
先输入 n , m n, m n,m 分别是池塘数量和天数,之后输入 n n n 行,每行一个数字表示水量变化,正数为增加,负数为减少,你需要输出每天的水量总和。
我的思路
暴力获得80%分数,遂摆:
#include<stdio.h>
#define MAX 1000005
typedef long long ll;
ll pool[MAX];
int main() {
int n, m;
scanf("%d%d", &n, &m);
for (int i = 0; i < m; i++) {
ll delta, sum = 0;
scanf("%lld", &delta);
for (int j = 1; j <= n; j++) {
pool[j] += delta;
if (pool[j] > j) pool[j] = j;
else if (pool[j] < 0) pool[j] = 0;
sum += pool[j];
}
printf("%lld\n", sum);
}
return 0;
}