Problem B. gWheels Google APAC 2016 University Test Round B

来源:互联网 发布:centos 7 安装desktop 编辑:程序博客网 时间:2024/06/05 19:00

pedal group的wheel记为p1,extra group的wheel记为e1,e2,tear group的wheel记为t1。

满足target ratio即为p1/e2*e2/t1=P/Q,namely,p1*e2*Q=e1*t1*P。那么可以枚举p1*e2的所有值,在搜索是否存在对应的组合e1*t1满足不等式。

可以预处理将所有的p1*e2存在数组leftarr中,将所有的e1*t1存在数组rightarr中,将leftarr排好序,就可以在给定一个p1*e2的值时,二分查找判断是否存在使得等式成立的e1*t1。

如果二分查找到的e1*t1是同一个extra geal,因为rightarr是排好序的,如果结果是yes,那么mid-1,mid+1处至少存在一个gear可以满足等式并且不是同一个extra geal。否则就不存在满足条件的两个extra geal。

感觉等式两边的值可能会溢出,所以用long long保险些。

#include<iostream>#include<stdio.h>#include<cstdio>#include<string>#include<cmath>#include<stdlib.h>#include<algorithm>#include<string.h>#include<cstring>#include<vector>#include<queue>#include<map>#include<set>using namespace std;//2016 Round B Problem B. gWheelsint T;const int maxn=2010;int P;int M;int Q;int Np;int Nt;int Ne;long long arrp[maxn];long long arrt[maxn];long long arre[maxn];pair<long long,int>leftarr[maxn*maxn];pair<long long,int>rightarr[maxn*maxn];int kgcd(int a,int b){    if(a==0) return b;    if(b==0) return a;    if(!(a&1)&&!(b&1)) return kgcd(a>>1,b>>1)<<1;    else if(!(b&1)) return kgcd(a,b>>1);    else if(!(a&1)) return kgcd(a>>1,b);    else return kgcd(abs(a-b),min(a,b));}bool cmp(pair<int,int>a,pair<int,int>b){    if(a.first==b.first)    {        return a.second<b.second;    }    return a.first<b.first;}bool binarysearch(long long val,int idxl){    int left=0;    int right=Nt*Ne;    int mid=(left+right)/2;    while(left<=right)    {        mid=(left+right)/2;        long long valr=rightarr[mid].first;        int idxr=rightarr[mid].second;        if(val*Q==valr*P)        {            if(idxl!=idxr)            {                return true;            }            else if(mid>0&&rightarr[mid-1].first==val)            {                return true;            }            else if(mid<Nt*Ne-1&&rightarr[mid+1].first==val)            {                return true;            }            return false;        }        else if(val*Q<valr*P)//valr is too large        {            right=mid-1;        }        else if(val*Q>valr*P)//valr is too small        {            left=mid+1;        }    }    return false;}int main(){    freopen("B-large-practice.in","r",stdin);//    freopen("input.txt","r",stdin);    freopen("output.txt","w",stdout);    scanf("%d",&T);    for(int ca=1;ca<=T;ca++)    {        printf("Case #%d:\n",ca);        memset(arrp,0,sizeof(arrp));        memset(arrt,0,sizeof(arrt));        memset(arre,0,sizeof(arre));        scanf("%d %d %d",&Np,&Ne,&Nt);        for(int i=0;i<Np;i++)        {            scanf("%lld",&arrp[i]);        }        for(int i=0;i<Ne;i++)        {            scanf("%lld",&arre[i]);        }        for(int i=0;i<Nt;i++)        {            scanf("%lld",&arrt[i]);        }        int cnt=0;        for(int i=0;i<Np;i++)        {            for(int j=0;j<Ne;j++)            {                leftarr[cnt++]=make_pair(arrp[i]*arre[j],j);            }        }        cnt=0;        for(int i=0;i<Nt;i++)        {            for(int j=0;j<Ne;j++)            {                rightarr[cnt++]=make_pair(arrt[i]*arre[j],j);            }        }        sort(rightarr,rightarr+cnt,cmp);        scanf("%d",&M);        for(int i=0;i<M;i++)        {            scanf("%d %d",&P,&Q);            int g=kgcd(P,Q);            P/=g;            Q/=g;            bool ans=false;            for(int i=0;i<Np*Ne;i++)            {                ans=binarysearch(leftarr[i].first,leftarr[i].second);                if(ans==true)                {                    printf("Yes\n");                    break;                }            }            if(ans==false)            {                printf("No\n");            }        }    }    return 0;}


0 0
原创粉丝点击