欢迎访问我的个人网站==》 jiashubing.cn

HDU 4768 Flyer(二分法)

题目链接: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”

Sample Input
2
1 10 1
2 10 1
4
5 20 7
6 14 3
5 9 1
7 21 12
 
Sample Output
1 1
8 1

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

代码如下:

 1 # include<iostream>
 2 # include<cstdio>
 3 # include<algorithm>
 4 # define LL __int64
 5 # define maxn 20010
 6 using namespace std;
 7 
 8 LL a[maxn],b[maxn],c[maxn];
 9 int n;
10 
11 int judge(LL l,LL r)
12 {
13     LL ret=0;
14     for(int i=1; i<=n; i++)
15     {
16         if(l>b[i] || r<a[i]) continue;
17         int k=a[i];
18         int j=min(r,b[i]);
19         if(j<k) continue;
20         ret += max(0LL, (j-k)/c[i]+1);
21     }
22     if(ret%2 == 1)
23         return 1;
24     return 0;
25 }
26 
27 int main()
28 {
29     while(scanf("%I64d",&n)!=EOF)
30     {
31         for(int i=1; i<=n; i++)
32             scanf("%I64d%I64d%I64d",&a[i],&b[i],&c[i]);
33         LL l=1;
34         LL r=4294967297;  //可用(__int64)1 << 32 + 1代替,必须加 __int64
35         LL tmp = -1;
36         while(l<=r)
37         {
38             LL mid=(l+r)/2;
39             if(judge(0,mid))
40             {
41                 r = mid - 1;
42                 tmp = mid;
43             }
44             else
45                 l= mid+1;
46         }
47         if(tmp==-1)
48             printf("DC Qiang is unhappy.\n");
49         else
50         {
51             int ans = 0;
52             for(int i=1; i<=n; i++)
53                 if(a[i]<=tmp && b[i]>=tmp &&(tmp-a[i])%c[i]==0)
54                     ans ++;
55             printf("%I64d %d\n",tmp,ans);
56         }
57     }
58     return 0;
59 }

 

posted @ 2013-09-30 08:54  贾树丙  阅读(254)  评论(0编辑  收藏  举报