POJ3484 Showstopper(二分)

来源:互联网 发布:日系进口厨刀知多少 编辑:程序博客网 时间:2024/06/04 01:11

题目看了好久……


然后感谢小伙伴给我讲了题意。


求出现了偶数次的那个数以及它出现的次数。


数论知识,偶+偶 = 偶, 偶+奇 = 奇 。所以当那个奇数出现之后,那之后的所有数的前数之和必定为奇数。出现规律大概是  偶偶偶偶偶偶偶奇奇奇奇奇……

这样只要二分查找第一个出现的奇数即可。


因为无法确定会有多少组数据,所以开动态数组。


#include <iostream>#include <cstdio>#include <sstream>#include <cstring>#include <vector>#include <algorithm>using namespace std;typedef long long ll;string s;ll num[4];struct node{    ll x,y,z;}t;vector<node> n;vector<node>::iterator iter;bool ok(ll m){    ll res = 0;    for(iter=n.begin();iter!=n.end();++iter)    {        node tem = *iter;        if(m>=tem.x)        {            ll mm = min(tem.y,m);            res+=(mm-tem.x)/tem.z+1;        }    }    return res%2==1;}ll sum(ll m){    ll res = 0;    for(iter=n.begin();iter!=n.end();++iter)    {        node tem = *iter;        if(m>=tem.x&&m<=tem.y)        {            if((m-tem.x)%tem.z == 0)                res++;        }    }    return res;}ll solve(){    ll l = 0;    ll r = 1LL<<33;    ll mid;    for(mid=(l+r)/2;l<=r;mid=(l+r)/2)    {        if(ok(mid))            r = mid-1;        else            l = mid+1;    }    return l;}int main(){    bool y = false;    int test = 0;    while(getline(cin,s))    {        stringstream ss(s);        int tt = 0;        while(ss>>num[tt])            tt++;        if(tt!=0)        {            t.x = num[0];            t.y = num[1];            t.z = num[2];            n.push_back(t);            y = true;            test++;        }        else        {            test = 0;            if(y)            {                ll a = solve();                if(a>=1LL<<33)                    printf("no corruption\n");                else                    printf("%I64d %I64d\n",a,sum(a));                n.clear();                y = false;            }        }    }    if(test)    {        ll a = solve();        if(a>=1LL<<33)            printf("no corruption\n");        else            printf("%I64d %I64d\n",a,sum(a));        y = false;    }    return 0;}


0 0
原创粉丝点击