Code Jam-- New Lottery Game

来源:互联网 发布:比较好的梵高传记知乎 编辑:程序博客网 时间:2024/06/05 19:58

原题:https://code.google.com/codejam/contest/dashboard?c=2994486#s=p1

题意:给定三个10^9以内的数A,B,K,问有多少个数对<x,y>在x < A且y < B的情况下使A&B < K。

题解:解题的基础在于求一个小于K的数的个数DP上。IsLessA为1代表已形成比特位前缀小于A的比特位前缀,为0代表前缀相等,其它详见注释。


#include<iostream>#include<cstdio>#include<cstring>using namespace std;int A,B,K;long long dp[32][2][2][2];bool _bit(int x,int bitPos){    return (x>>bitPos)&1;}long long calcLessNum(int bitPos,bool IsLessA,bool IsLessB,bool IsLessK)<span style="white-space:pre"></span>//能进入递归,则已形成的三个数一定分别小于等于A且小于等于B且小于等于K{    long long num = dp[bitPos][IsLessA][IsLessB][IsLessK];    if(bitPos == -1)    {        return IsLessA&IsLessB&IsLessK;    }    if(num)        return num;    bool IsLessA_next = IsLessA|_bit(A,bitPos);    bool IsLessB_next = IsLessB|_bit(B,bitPos);    bool IsLessK_next = IsLessK|_bit(K,bitPos);    num += calcLessNum(bitPos-1,IsLessA_next,IsLessB_next,IsLessK_next);      //A,B,K的bitpos位置都放上0,肯定能再往下递归    if(IsLessA_next)    {        num += calcLessNum(bitPos-1,IsLessA,IsLessB_next,IsLessK_next); //A的bitpos位置放上1,,B和K的位置上都放上0    }    if(IsLessB_next)    {        num += calcLessNum(bitPos-1,IsLessA_next,IsLessB,IsLessK_next); //B的bitpos位置上放上1,A和K的位置上都放上0    }    if(IsLessA_next&IsLessB_next&IsLessK_next)    {        num += calcLessNum(bitPos-1,IsLessA,IsLessB,IsLessK);   //A,B,K的bitpos位置上都放上1    }    return dp[bitPos][IsLessA][IsLessB][IsLessK] = num;}int main(){    int T;    scanf("%d",&T);    for(int t = 1;t <= T;t++)    {        scanf("%d%d%d",&A,&B,&K);        memset(dp,0,sizeof(dp));        printf("Case #%d: %lld\n",t,calcLessNum(31,0,0,0));    }    return 0;}


0 0
原创粉丝点击