题目描述
现在工厂里有三根铁棒,分别长为
a
,
b
,
c
a,b,c
a,b,c,现在你可以对其中一些铁棒进行加长,但总的加长长度 不能超过L,问有多少种加长的方案使得加长后的铁棒可以构成三角形。
输入格式
共一行,包含4 个整数
a
,
b
,
c
,
L
(
1
≤
a
,
b
,
c
≤
3
e
5
,
0
≤
L
≤
3
e
5
)
a,b,c,L (1≤a,b,c≤3e5, 0≤L≤3e5)
a,b,c,L(1≤a,b,c≤3e5,0≤L≤3e5)。
输出格式
一行一个整数表示答案
输入输出样例
输入 #1
1 1 1 2
输出 #1
4
输入 #2
1 2 3 1
输出 #2
2
输入 #3
10 2 1 7
输出 #3
0
说明/提示
数据范围
对于30%的数据:
a
,
b
,
c
<
=
100
a,b,c<=100
a,b,c<=100
对于另外20%的数据:
L
<
=
10
L<=10
L<=10
对于100%的数据:
1
<
=
a
,
b
,
c
<
=
3
e
5
,
0
<
=
L
<
=
3
e
5
1<=a,b,c<=3e5,0<=L<=3e5
1<=a,b,c<=3e5,0<=L<=3e5
样例解释
4种方案为:
(1) 给a加长1,给b加长1
(2) 给a加长1,给c加长1
(3) 给b加长1,给c加长1
(4) 不加长
解题思路
考虑容斥,首先用 隔板法 求出加长的总方案数为
C
(
L
+
4
−
1
,
3
)
C(L+4-1,3)
C(L+4−1,3),再考虑算出不合法的加长方案数
构不成三角形则
a
+
x
+
b
+
y
<
=
c
+
z
a+x+b+y<=c+z
a+x+b+y<=c+z,且
x
+
y
+
z
<
=
L
x+y+z<=L
x+y+z<=L
则
x
+
y
<
=
m
i
n
(
c
+
z
−
a
−
b
,
L
−
z
)
x+y<=min(c+z-a-b,L-z)
x+y<=min(c+z−a−b,L−z)
于是枚举z,则知道
x
+
y
x+y
x+y最大是多少,再用隔板法求出这种条件下
x
,
y
x,y
x,y的方案数即可
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
long long a,b,c,l,ans;
long long lyx(long long x,long long y,long long z,long long w)
{
long long s=x+y+z+w,t=0;
long long ans=0;
for(int i=0;i<=w;i++)
{
t=min(s-i-x,i+x);
if(y+z<=t)
{
ans+=(t-y-z+1)*(t-y-z+2)/2;
}
}
return ans;
}
int main()
{ scanf("%lld%lld%lld%lld",&a,&b,&c,&l);
ans=(l+1)*(l+2)*(l+3)/6;
ans-=lyx(a,b,c,l);
ans-=lyx(b,a,c,l);
ans-=lyx(c,b,a,l);
printf("%lld",ans);
}