您的位置:首页 > 其它

HDU-5720 Wool

2016-07-18 20:13 363 查看


Wool

 
 Accepts: 109
 
 Submissions: 770

 Time Limit: 8000/4000 MS (Java/Others)
 
 Memory Limit: 262144/262144 K (Java/Others)

问题描述
黎明时,Venus为Psyche定下了第二个任务。她要渡过河,收集对岸绵羊身上的金羊毛。

那些绵羊狂野不驯,所以Psyche一直往地上丢树枝来把它们吓走。地上现在有nn根树枝,第ii根树枝的长度是a_ia​i​​.

如果她丢的下一根树枝可以和某两根树枝形成三角形,绵羊就会被激怒而袭击她。

现在Psyche手中只有长度不小于LL且不大于RR的树枝。请你帮忙计算,她下一根可以丢多少种不同长度的树枝而不会把绵羊激怒呢?

输入描述
第一行,一个整数T (1 \le T \le 10)T(1≤T≤10),代表数据组数。

对于每组数据,第一行有三个整数n,L,Rn,L,R (2 \le n \le 10 ^ 5, 1 \le L \le R \le 10 ^ {18})(2≤n≤10​5​​,1≤L≤R≤10​18​​)。

第二行,nn个整数,第ii个整数为a_ia​i​​ (1 \le a_i \le 10 ^ {18})(1≤a​i​​≤10​18​​),代表第ii根树枝的长度。

输出描述
输出TT行,对于每组数据,输出选取方式总数。

输入样例
2
2 1 3
1 1
4 3 10
1 1 2 4

输出样例
2
5

Hint
对于第一组数据,可以选用长度为2, 32,3的树枝。

对于第二组数据,可以选用长度为6, 7, 8, 9, 106,7,8,9,10的树枝。


解题思路:

考虑三角形的判断条件,a + b > c && a - b < c(a >= b)

那么只需要把未知的那个边当作c这条边,已知的当作a,b两条边

然后求在[l, r]区间内,不属于(a-b, a+b)的区间里的整数即可

代码如下:

#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<LL, LL > pi;
const int maxn = 1e5;
pi b[maxn];
LL a[maxn];
bool cmp(pi x, pi y){
return (x.first == y.first ? (x.second > y.second) : (x.first < y.first));
}
int main()
{
// freopen("test.in", "r+", stdin);
// freopen("test.out", "w+", stdout);
LL t, n, L, R;
scanf("%lld", &t);
while(t--){
scanf("%lld%lld%lld", &n, &L, &R);
for(int i = 0; i < n; ++i) scanf("%lld", &a[i]);
sort(a, a + n);
for(int i = 0; i < n - 1; ++i){
b[i].first = a[i+1] - a[i];
b[i].second = a[i+1] + a[i];
}
if(n - 1 >= 2)
sort(b, b + n - 1, cmp);
LL ans = 0, tmp1 = L, tmp2 = L;
for(int i = 0; i < n - 1; ++i){
if(b[i].second <= L) continue;
if(b[i].first > R) break;

if(b[i].first >= tmp2){
tmp1 = b[i].first;
ans += tmp1 - tmp2 + 1;
}
if(b[i].second > tmp2){
tmp2 = b[i].second;
}
if(tmp2 > R){
tmp2 = R + 1;
break;
}
}
ans += (R >= tmp2 ? (R - tmp2 + 1) : 0 );
printf("%lld\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  暴力