您的位置:首页 > 其它

HDU 4768 Flyer(二分法)

2013-09-30 08:54 351 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4768

题目大意:每组数据有n行输入,每行有三个数A、B、C,A<=B且小于2^32,从A到B每隔C个数发一份传单,最后所有发过传单的数中每一个数发了奇数次传单的是倒霉的那个人,倒霉的人最多只有1个。如果存在这个人输出他的序号和传单数,否则输出“DC Qiang is unhappy”

[align=left]Sample Input[/align]

2
1 10 1
2 10 1
4
5 20 7
6 14 3
5 9 1
7 21 12

[align=left]Sample Output[/align]

1 1

8 1

分析:直接模拟会超时,二分的奇妙运用

代码如下:

# include<iostream>
# include<cstdio>
# include<algorithm>
# define LL __int64
# define maxn 20010
using namespace std;

LL a[maxn],b[maxn],c[maxn];
int n;

int judge(LL l,LL r)
{
LL ret=0;
for(int i=1; i<=n; i++)
{
if(l>b[i] || r<a[i]) continue;
int k=a[i];
int j=min(r,b[i]);
if(j<k) continue;
ret += max(0LL, (j-k)/c[i]+1);
}
if(ret%2 == 1)
return 1;
return 0;
}

int main()
{
while(scanf("%I64d",&n)!=EOF)
{
for(int i=1; i<=n; i++)
scanf("%I64d%I64d%I64d",&a[i],&b[i],&c[i]);
LL l=1;
LL r=4294967297;  //可用(__int64)1 << 32 + 1代替,必须加 __int64
LL tmp = -1;
while(l<=r)
{
LL mid=(l+r)/2;
if(judge(0,mid))
{
r = mid - 1;
tmp = mid;
}
else
l= mid+1;
}
if(tmp==-1)
printf("DC Qiang is unhappy.\n");
else
{
int ans = 0;
for(int i=1; i<=n; i++)
if(a[i]<=tmp && b[i]>=tmp &&(tmp-a[i])%c[i]==0)
ans ++;
printf("%I64d %d\n",tmp,ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: