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 }
把每一件简单的事情做好,就是不简单;把每一件平凡的事情做好,就是不平凡!相信自己,创造奇迹~~