51NOD 1509 加长棒 && Codeforces 571 A. Lengthening Sticks(组合数学 + 挡板法)

[传送门](http://codeforces.com/contest/571/problem/A)
A. Lengthening Sticks
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given three sticks with positive integer lengths of a, b, and c centimeters. You can increase length of some of them by some positive integer number of centimeters (different sticks can be increased by a different length), but in total by at most l centimeters. In particular, it is allowed not to increase the length of any stick.

Determine the number of ways to increase the lengths of some sticks so that you can form from them a non-degenerate (that is, having a positive area) triangle. Two ways are considered different, if the length of some stick is increased by different number of centimeters in them.

Input

The single line contains 4 integers a, b, c, l (1 ≤ a, b, c ≤ 3·105, 0 ≤ l ≤ 3·105).

Output

Print a single integer — the number of ways to increase the sizes of the sticks by the total of at most l centimeters, so that you can make a non-degenerate triangle from it.

Examples
Input
1 1 1 2
Output
4
Input
1 2 3 1
Output
2
Input
10 2 1 7
Output
0
Note

In the first sample test you can either not increase any stick or increase any two sticks by 1 centimeter.

In the second sample test you can increase either the first or the second stick by one centimeter. Note that the triangle made from the initial sticks is degenerate and thus, doesn’t meet the conditions.

题目大意:

现在有三根木棒,他们的长度分别是 a , b , c 厘米。你可以对他们进行加长(不同的木棒可以增加不同的长度),他们总的加长长度不能

超过 L 厘米。你也可以不对他们进行加长。现在请你计算一下有多少种加长的方式使得他们能构成合法的三角形(面积非 0 )。

解题思路:

这个题目直接想的话 没法做,所以就是间接的想,也就是采用容斥原理从反面来想,也就是说 用总数减去不能够满足三角形的方法数,那么先来

求总数,因为现在的问题是将 L 分成四份, 一份给 a 一份给 b 一份给 c 剩下的就是剩下的了,那么分成的四份可能有 0, 不满足

挡板法的条件,所以我们就将 L+4 ,那么现在在分成四份就符合条件啦,所以总的方法数就是 C(L+41,41) , 那么现在再来求不满足

三角形条件的方法数,因为三角形一定满足一个条件是 所以我们只要求出 两条较小的边小于等于最大边就不满足条件了,

然后根据这个可以列一个方程,假设 a 现在加上了 x , b 现在加上了 y c 现在加上了 z(假设 a 是最大边),方程如下:

b+y+c+za+x

然后因为所有数的和一定是 a+b+c+L ,所以最大值不可能超过 a+b+c+L ,那么 b+ca+b+c+L(a+x) 综上 所以有 b+cmin(a+b+c+La,a+x)

然后在利用挡板法求出 不能组成三角形的方法数,是 C(minbc+2,2) 所以就可以写了。

MyCode

/**
2016 - 09 - 16 下午
Author: ITAK

Motto:

今日的我要超越昨日的我,明日的我要胜过今日的我,
以创作出更好的代码为目标,不断地超越自己。
**/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 1e9+5;
const LL MAXN = 1e6+5;
const LL MOD = 1e9+7;
const double eps = 1e-7;
const double PI = acos(-1);
using namespace std;
int Scan_Int()///输入外挂
{
    int res=0,ch,flag=0;
    if((ch=getchar())=='-')
        flag=1;
    else if(ch>='0'&&ch<='9')
        res=ch-'0';
    while((ch=getchar())>='0'&&ch<='9')
        res=res*10+ch-'0';
    return flag?-res:res;
}
LL Scan_LL()///输入外挂
{
    LL res=0,ch,flag=0;
    if((ch=getchar())=='-')
        flag=1;
    else if(ch>='0'&&ch<='9')
        res=ch-'0';
    while((ch=getchar())>='0'&&ch<='9')
        res=res*10+ch-'0';
    return flag?-res:res;
}
void Out(LL a)///输出外挂
{
    if(a>9)
        Out(a/10);
    putchar(a%10+'0');
}
LL Solve(LL a, LL b, LL c, LL L)///a 是三边之间最大的
{
    LL tmp1 = a + b + c + L;
    LL ans = 0;
    for(LL i=0; i<=L; i++)
    {
        LL tmp = min(tmp1-a-i, i+a);
        if(b + c <= tmp)
            ans += (tmp-b-c+2)* (tmp-b-c+1) / 2;
    }
    return ans;
}
int main()
{
    LL a, b, c, L;
    while(cin>>a>>b>>c>>L)
    {
        LL ans = (L+3) * (L+2) * (L+1) / 6;
        ans -= Solve(a, b, c, L);
        ans -= Solve(b, a, c, L);
        ans -= Solve(c, a, b, L);
        cout<<ans<<endl;
    }
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值