1509 加长棒

                       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
System Message (题目提供者)
 
 
这个竟然是组合数。。
直接计算合法的三角形是有些麻烦的,所以我们就用总数减去不合法的数
我们要把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) {;}
代码

 

posted @ 2017-10-10 20:14  拿叉插猹哈  阅读(212)  评论(0编辑  收藏  举报