小欧找数
[题目链接](https://www.nowcoder.com/practice/e821e1ea74a742208a34b4588b2d78e1)
思路
给定两个区间 和
,要求有多少个整数
,使得存在整数
和
,满足
。
转化问题
既然 可以取遍
,
可以取遍
,那么
的取值范围就是连续整数区间
。
设 ,问题变成:当
取遍
中所有整数时,
能产生多少种不同的值?
关键观察
是一个不递减的函数。当
从最小值连续增大到最大值时,
也从最小值连续增大到最大值(每两个连续的
值产生同一个
值)。
因此, 的取值是一段连续的整数区间,答案就是:
$$
举例
以样例 为例:
的范围是
,
,
,
,
- 不同的值为
,共
个
用公式计算:,一致。
复杂度分析
- 时间复杂度:
,只需读入四个数并做一次加法和除法。
- 空间复杂度:
。
代码
#include <bits/stdc++.h>
using namespace std;
int main() {
long long l1, r1, l2, r2;
cin >> l1 >> r1 >> l2 >> r2;
long long lo = l1 + l2;
long long hi = r1 + r2;
auto floorDiv = [](long long a, long long b) -> long long {
return a / b - (a % b != 0 && (a ^ b) < 0);
};
cout << floorDiv(hi, 2) - floorDiv(lo, 2) + 1 << endl;
return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long l1 = sc.nextLong(), r1 = sc.nextLong();
long l2 = sc.nextLong(), r2 = sc.nextLong();
long lo = l1 + l2;
long hi = r1 + r2;
System.out.println(Math.floorDiv(hi, 2) - Math.floorDiv(lo, 2) + 1);
}
}

京公网安备 11010502036488号