1509 加长棒
题目来源: CodeForces
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
收藏
关注
现在有三根木棒,他们的长度分别是a,b,c厘米。你可以对他们进行加长(不同的木棒可以增加不同的长度),他们总的加长长度不能超过L厘米。你也可以不对他们进行加长。
现在请你计算一下有多少种加长的方式使得他们能构成合法的三角形(面积非0)。
Input
单组测试数据。 共一行,包含4 个整数a,b,c,L (1≤a,b,c≤3*10^5, 0≤L≤3*10^5)。
Output
输出答案占一行。
Input示例
1 1 1 2
Output示例
4
这个竟然是组合数。。
直接计算合法的三角形是有些麻烦的,所以我们就用总数减去不合法的数
我们要把L分成4份 一份加在a上 一份加在b上 一份加在c上 还有一份不动 可以为0
当然这样是看不出组合来的 因为有0的存在 所以我么要去掉0的影响 把L加4 这样每一份最少为1
这就是明显的隔板法 这L+4-1个空中插入三个板 分成4部分
这是总的方案数
三角形 有两边之和大于第三边 所以有 a+x+b+y>z+c;
题目中还有 x+y+z<=L ==> x+y<=min(c+z-a-b,L-z) 即为不合法三角形的条件
所以我们可以枚举z 把x+y分到另外两个棒上去 这又是隔板法 即在(x+y+3)-1个空中插入两个板
用总的方案数减去不合法的方案数 即为ans
1 #include <cstdio> 2 #include <cctype> 3 #define min(a,b) a<b?a:b 4 5 typedef long long LL; 6 7 LL a,b,c,l; 8 9 inline void read(LL&x) { 10 int f=1;register char c=getchar(); 11 for(x=0;!isdigit(c);c=='-'&&(f=-1),c=getchar()); 12 for(;isdigit(c);x=x*10+c-48,c=getchar()); 13 x=x*f; 14 } 15 16 inline LL NOT(LL a,LL b,LL c,LL l) { 17 LL cnt=0; 18 for(int z=0;z<=l;++z) { 19 LL x=min(c+z-a-b,l-z); 20 if(x>=0) cnt+=(x+1)*(x+2)/2; 21 } 22 return cnt; 23 } 24 25 int hh() { 26 read(a);read(b);read(c);read(l); 27 LL ans=(l+3)*(l+2)*(l+1)/6; 28 ans-=NOT(a,b,c,l); 29 ans-=NOT(a,c,b,l); 30 ans-=NOT(b,c,a,l); 31 printf("%lld\n",ans); 32 return 0; 33 } 34 35 int sb=hh(); 36 int main(int argc,char**argv) {;}
作者:乌鸦坐飞机
出处:http://www.cnblogs.com/whistle13326/
新的风暴已经出现
怎么能够停止不前
穿越时空 竭尽全力
我会来到你身边
微笑面对危险
梦想成真不会遥远
鼓起勇气 坚定向前
奇迹一定会出现