题意:
学校内有N个社团,且由于该学校的人数众多,所以第i个社团分发广告时,是从Ai开始,到Ai+K*Ci<=Bi,且Ai+(K+1)*Ci<=Bi,现要你求得是一个学生的编号,且满足该学生拿的广告份数是奇数份,且该学生最多只能出现一个。
解题思路:
二分,因为学生最多只能出现一个,所以当我们二分到一个区间时,统计该区间得到广告数的总数,如果是偶数且肯定在更大的区间内,如果是奇数,则再更小的区间内。
注意:
可能会超int,且Ci可能为零。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define MAXN0 20010
int A[MAXN0],B[MAXN0],C[MAXN0],N;
int L,R;
int cal(int up,int &ss){
int ans = 0;
ss = 0;
for(int i=0;i<N;++i){
if(B[i]<=up){
if(!C[i]){
ans++;
}
else {
ans += (B[i] - A[i])/C[i]+1;
}
}
else {
if(A[i]<=up){
if(!C[i]){
ans++;
}
else {
ans+=(up - A[i])/C[i]+1;
}
}
}
if(up<=B[i]&&up>=A[i]){
if(C[i]==0){
if(up==A[i]){
++ss;
}
}
else {
if((up-A[i])%C[i]==0){
++ss;
}
}
}
}
return ans;
}
void solve(){
int Mid;
int tmp,tmp1;
while(L<R){
Mid = L + (R - L)/2;
tmp = cal(Mid,tmp1);
if(tmp&1){
R = Mid;
}
else {
L = Mid+1;
}
}
tmp = cal(L,tmp1);
if(tmp&1){
printf("%d %d\n",L,tmp1);
}
else {
printf("DC Qiang is unhappy.\n");
}
}
int main(){
while(scanf("%d",&N)!=EOF){
for(int i=0;i<N;++i){
scanf("%d%d%d",&A[i],&B[i],&C[i]);
if(!i){
L = A[i];
R = B[i];
}
else{
if(L>A[i]){
L = A[i];
}
if(R<B[i]){
R = B[i];
}
}
}
solve();
}
return 0;
}