POJ---3484(Showstopper,二分)

题意:

给定若干个等差序列,这些个等差序列中每个元素出现的次数为偶数才算正常,现在有一个BUG:仅有个元素出现了奇数次,让你找出这个元素和它出现的次数!

 

题解:

找特性:仅有一个元素出现了奇数次。举个栗子。

1 2 3 4 5 6 7 8 9 10

     4

1 2 3 4 5

         6 7 8 9 10

 

 

很明显bug元素是4。也就是前面的元素1 2 3 和后面的元素 5 6 7 8 9 10都出现了偶数次。

规律出来了:

<=X的元素个数为偶数的时候,说明bug元素>X<=X的元素个数为奇数的时候,说明bug元素<=X。二分的有序性就出来了!

 PS:输入故意刁难~~~

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<string>
#include<cstring>
#include<vector>
#include<functional>

using namespace std;

typedef unsigned long long ULL;

vector<ULL>x,y,z;


int N;//数据组数

char buf[100];
bool input()
{
     x.clear();y.clear();z.clear();
     bool have=false;
     while(gets(buf))
     {
         if(!strlen(buf))if(have)break;else continue;
         ULL xx,yy,zz;
         sscanf(buf,"%I64d%I64d%I64d",&xx,&yy,&zz);
         have=true;
         x.push_back(xx);
         y.push_back(yy);
         z.push_back(zz);


     }
     N=x.size();
     return have;
}

ULL Countsum(ULL mid)
{
      ULL sum=0;
      for(int i=0;i<N;i++)
      {
          if(mid>=y[i])
            sum+=(y[i]-x[i])/z[i]+1;
          else if(mid>=x[i])
            sum+=(mid-x[i])/z[i]+1;

      }
      return  sum;

}

int main()
{
    while(input())
    {
         ULL lb=0,ub=0xffffffff;//42亿多点
         while(ub-lb>1)
         {
             ULL mid=(lb+ub)>>1;
             if(Countsum(mid)&1)ub=mid;//出现奇数,缩小范围(mid变小)去找最优可行解。
             else  lb=mid;

         }
         if((lb+1)==0xffffffff)puts("no corruption");//没有的话,lb一直往右走。
         else
         cout<<ub<<' '<<Countsum(ub)-Countsum(ub-1)<<endl;//最后的BUG数一定是给ub了!
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值