先贴个题目:
以及原题链接: 730. 机器人跳跃问题 - AcWing题库https://www.acwing.com/problem/content/732/
先说说思路,第一眼看上去像是什么之前写过几次(没写出来,也没看题解) 的什么类似子数列合为零啊之类的题目,结果仔细看看还是有区别的,至于二分说实在话一开始想不出来咋二分,然后暴力超时了,就明白二分找答案了。找一个最小的数当线段起点,找一个合适的数做线段终点,这题基本可以说是写完了(大概),那一看最小能量0嘛,最大?数列中的最大数最为能量肯定能过,毕竟全是正的对吧。然后我就开始码代码了
如下:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
int n;
long long min = 0, max = -1, mid;
cin >> n;
int *a = new int[n + 10];
for (int i = 0; i < n; ++i)
{
scanf("%d", &a[i]);
if (a[i] > max)
max = a[i];
}
while (max > min)
{
int sign = 1;
mid = (max + min) / 2;
long long e = mid;
for (int i = 0; i < n; ++i)
{
e -= (a[i] - e);
e %= (long long)1e10;
if (e < 0)
{
sign = 0;
break;
}
}
if (sign)
max = mid;
else
min = mid + 1;
}
cout << min;
return 0;
}
看着挺短的对不对,其实也不难,说几个注意点,刚开始看这个题目觉得不会爆数据,然后样例过了,一交,爆了,开longlong,emmm。。。。又爆了!罪魁祸首其实就是他的逻辑,当你能量值比较大的时候,你每次基本都是在做乘2的运算,而最大数据有10的五次方,也就是说你的数字大小可能是2的10的五次方这个数量级的!!!这开longlonglonglong都没用。没办法了,我想了半天,最后整了个暴力方法:
e %= (long long)1e10
我直接不让你超过10位,ok问题解决,皆大欢喜。
PS:讲个题外话,这题算是我1月30的刷题,那为啥我这个点还在苦逼的写题解呢?因为我这个(龙门脏话)看错答案了,其中longlong 爆了的一组数据答案是53,我看成51了,然后我自己做的时候又一直没发现,这本来是我昨晚11点打算做完就睡的题,确实40分就做完了,结果因为答案和标答老差2百思不得其解,甚至重写了一边代码,最后手算才发现我记得的答案有问题,回原网站看了一眼,浪费了我两个小时。。。。什么?你问才浪费两小时为什么4点才发,emmm我发现之后破大方缓了一会儿吃了个夜宵回来写的,顺带一提,我的夜宵是火鸡面加炸鸡,真的香大伙们。继续写题解去了。
by————2024.1.30刷题记录