链接:
https://www.51nod.com/Challenge/Problem.html#problemId=1509
题意:
现在有三根木棒,他们的长度分别是 a,b,c厘米。你可以对他们进行加长(不同的木棒可以增加不同的长度),他们总的加长长度不能超过 L厘米。你也可以不对他们进行加长。
现在请你计算一下有多少种加长的方式使得他们能构成合法的三角形(面积非 0)。
输入样例
1 1 1 2
输出样例
4
思路:
定义x,y,z分别为加上a,b,c上的距离,但是前提是 c为最长的,上图3式为不满足三角形的约数条件,所以思路就是所有情况-不满足条件的情况,就为正确答案,因为假设了c为最长边,所以需要进行三次计算累加,分别以a,b,c来做长边。
现在的问题是知道x+y+z<=N,x,y,z三个值有多少取值情况呢?这里就用到了 隔板法,显然取值时,有四个数,x+y+z+t(没有使用的长度),所以就是在N这个数的N-1个空格中插入3个板子,但是因为x,y,z有可能取0(相当于两个板重叠了),所以将N+4就行了,默认每一块中至少1个,这样就可以算出。
AC代码:
#include<bits/stdc++.h>
#include<limits.h>
#define ll long long
#define endl "\n"
const int N=1e6+5;
const int INF=0x3f3f3f3f;
const int MOD=1e9+7;
const double eps=1e-6;
using namespace std;
int a,b,c,l;
ll C(int d, int u){
ll sum=1;
for(int i=d;i>d-u;--i) sum*=i;
for(int i=1;i<=u;++i) sum/=i;
return sum;
}
ll solve(int aa, int bb, int cc, int LL){
ll ans=0;
for(int z=0;z<=LL;++z){
int tmp=min(cc+z-aa-bb,LL-z);
if(tmp>=0) ans+=C(tmp+2,2);
}
return ans;
}
int main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>a>>b>>c>>l;
ll sum=C(l+3,3);
sum-=solve(a,b,c,l);
sum-=solve(a,c,b,l);
sum-=solve(b,c,a,l);
cout<<sum<<endl;
return 0;
}