版权声明:欢迎大家转载,转载请注明出处 https://blog.csdn.net/hao_zong_yin/article/details/83583334
题意:给定三个木棍,长度为a b c,现在可以给任意木棍增加任意长度(整数),但是增加的长度总数不能超过l(3e5),问有多少种增加方式使得增加完长度后的三个木棍可以构成一个三角形
思路:刚开始想到枚举一个最长的木棍,然后枚举该木棍增加的长度,然后计算另外两个木棍的合法情况数,但是不是很好计算,因为合法即要考虑两边之和大于第三边,有要考虑另外两个木棍增加长度后不能超过当前枚举的木棍的长度(因为我们一开始假设这根木棍最长),但是反着想就比较好像,我们首先算一下所有分配情况,然后按照上述的方法枚举,减去非法情况,对于非法情况我们只要考虑两边之和小于等于第三边即可,因为两边之和小于第三边了两边的长度一定都小于第三边,不会破坏当前枚举的木棍是最长的这个假设。
中间的计算都是经典的组合数问题,想一下就好了
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int a, b, c, l;
ll cal(int x) {
return 1LL*(x+2)*(x+1)/2;
}
ll cal_(int x, int y, int z) {
ll ans = 0;
for (int i = 0; i <= l; i++) {
if (x + i < y + z) continue;
int t = min(x + i - y - z, l - i);
ans += 1LL*(t+2)*(t+1)/2;
}
return ans;
}
int main() {
scanf("%d %d %d %d", &a, &b, &c, &l);
ll ans = 0;
for (int i = 0; i <= l; i++) {
ans += cal(i);
}
ans -= cal_(a, b, c);
ans -= cal_(b, a, c);
ans -= cal_(c, a, b);
printf("%lld\n", ans);
return 0;
}