题目 A1046
-
题意
简单的环,计算最小距离。这里要注意不要暴力超时。 -
思路
这里我开始的暴力方法导致超时了,然后看解析,这里的做法主要是先将结果计算出来,之后查询的时候o(1)
就能计算出来。主要采用的是前缀和的方式。因为是个环所以距离不是取left-1 ~ right-1
就是取另一半,所以这里把所有距离和sum
计算出来了,然后dis
数组中存放前缀和,这里需要注意的是a[i]
表示的是i ~ i+1
的距离,最后可以表示N~1
的距离。 -
Code in C++
#include <iostream>
#include <algorithm>
#define maxn 100005
int dis[maxn], a[maxn];
int main()
{
int n;
std::cin >> n;
int sum = 0;
for (int i = 1; i <= n; ++i) {
std::cin >> a[i];
sum += a[i];
dis[i] = sum;
}
int m;
std::cin >> m;
for (int i = 0; i < m; ++i) {
int left, right;
std::cin >> left >> right;
if (left > right) std::swap(left, right);
std::cout << std::min(sum-dis[right-1]+dis[left-1],dis[right-1]-dis[left-1]) << std::endl;
}
return 0;
}
题目 A1065
-
题意
判断A+B>C,但是因为会超过最大的范围,判断方法需要注意,这一题和B
1011我使用的是相同方法。 -
思路
- 通过ABC的关系去判断,避免会超范围的操作。
A>0, B>0 A+B<0
正溢出负数 true;A<0, B<0, A+B>=0
负溢出正数,false;其他正常判断。
- Code in C++
#include <iostream>
int main()
{
int T;
std::cin >> T;
for(int i = 1; i <= T; ++i) {
long long a,b,c;
std::cin >> a >> b >> c;
bool flag = false;
// judge A+B > C
if ((a > c && b >=0) || (b > c && a >= 0)) {
flag = true;
} else if ((a > 0 && c > 0) || (a < 0 && c < 0)) {
flag = (c - a) >= b ? false: true;
}
std::cout << "Case #" << i << ": ";
std::cout << (flag? "true" : "false") << std::endl;
}
return 0;
}
小结
- 10^9操作会超过100ms限制。
- 前缀和查询的使用。
- 溢出的判断。