[Java] 计蒜客---蒜头君的玩具
原创
©著作权归作者所有:来自51CTO博客作者tizzi的原创作品,请联系作者获取转载授权,否则将追究法律责任
一、内容
二、思路
- 用差分数组算出每个点总共被包含了几次,比如1-4就等于1-4区间的数组都加上1。这样a数组最终保存的就是装了这个点总共被覆盖几次。
- 由于每次只能选3条线段,所以数组里面每个点的值必须>=3才符合要求,要后从求一个c3a[i], a[i]表示这个点覆盖的次数,从里面能选出3条线段覆盖的种数。
- 对所有点都求一次组合数,然后所有的组合数相加 / c3m 就是结果了。由于可能不能整除,所以还要求一次gcd。
-note: 当m <= 2 时,直接输出0,因为都不满足。
三、代码
import java.io.PrintWriter;
import java.util.Scanner;
public class M_蒜头君的玩具 {
static int[] a = new int[50005];
static int[] d = new int[50005];
static int n, m, l, r;
static long x, y;
static PrintWriter out = new PrintWriter(System.out);
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
for (int i = 1; i <= m; i++) {
l = sc.nextInt();
r = sc.nextInt();
d[l] += 1;
d[r + 1] -= 1;
}
for (int i = 1; i <= n; i++) {
a[i] = d[i] + a[i - 1];
if (a[i] >= 3) {
x += c(a[i]);
}
}
y = c(m);
if (x == 0 || m <= 2) {
out.println(0);
} else {
long gcd = gcd(x, y);
x /= gcd;
y /= gcd;
if (x % y == 0) {
out.println(x / y);
} else {
out.println(x + "/" + y);
}
} out.close();
}
static long gcd(long a, long b) {
if (b == 0) return a;
return gcd(b, a % b);
}
static long c(long m) {
return m * (m - 1) * (m - 2) / 6;
}
}