Poj 3252 Round Numbers

Round Numbers

Description

The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, Paper, Stone' (also known as 'Rock, Paper, Scissors', 'Ro, Sham, Bo', and a host of other names) in order to make arbitrary decisions such as who gets to be milked first. They can't even flip a coin because it's so hard to toss using hooves.

They have thus resorted to "round number" matching. The first cow picks an integer less than two billion. The second cow does the same. If the numbers are both "round numbers", the first cow wins,
otherwise the second cow wins.

A positive integer N is said to be a "round number" if the binary representation of N has as many or more zeroes than it has ones. For example, the integer 9, when written in binary form, is 1001. 1001 has two zeroes and two ones; thus, 9 is a round number. The integer 26 is 11010 in binary; since it has two zeroes and three ones, it is not a round number.

Obviously, it takes cows a while to convert numbers to binary, so the winner takes a while to determine. Bessie wants to cheat and thinks she can do that if she knows how many "round numbers" are in a given range.

Help her by writing a program that tells how many round numbers appear in the inclusive range given by the input (1 ≤ Start < Finish ≤ 2,000,000,000).

Input

Line 1: Two space-separated integers, respectively Start and Finish.

Output

Line 1: A single integer that is the count of round numbers in the inclusive range Start..Finish

Sample Input

2 12

Sample Output

6

Answer

題意,

如果某個數字化爲二進制,0的數量比1的多,叫做Round Numbers

找[l,r]之間的所有Round Numbers

講解看代碼:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define maxn (35 + 20)
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
using namespace std;
typedef long long int LLI;

int dp[2][maxn][maxn];//dp[x][i][j]代表最高位是x,一共i位,其中0有j個的情況有多少種
int bit[maxn];


void getdp() {
    memset(dp,0,sizeof(dp));
    dp[0][1][1] = 1;//最開始的時候,長度爲1的,0算一種,1算一種,分別是dp[0][1][1]=dp[1][1][0]=1
    dp[1][1][0] = 1;
    /**
    然後狀態轉移方程是:
    如果我在1前面接了一個0那麼dp[0][i + 1][j + 1] += dp[1][i][j];
    如果我在1前面接了一個1那麼dp[1][i + 1][j] += dp[1][i][j];
    如果我在0前面接了一個0那麼dp[0][i + 1][j + 1] += dp[0][i][j];
    如果我在0前面接了一個1那麼dp[1][i + 1][j] += dp[0][i][j];
    **/
    for(int i = 1; i <= 33; i ++) {
        for(int j = 0; j <= 33; j ++) {
            if(dp[0][i][j] != 0) {
                dp[0][i + 1][j + 1] += dp[0][i][j];
                dp[1][i + 1][j] += dp[0][i][j];
            }
            if(dp[1][i][j] != 0) {
                dp[0][i + 1][j + 1] += dp[1][i][j];
                dp[1][i + 1][j] += dp[1][i][j];
            }
        }
    }
}
/**
預處理之後,從最高位開始(最高位一定是1)
在最高位放0,然後接下來每一位,都算以當前位爲最高位且爲1且0數量大於1數量的所有狀況
在最高位放1,接下來枚舉所有位,如果當前位爲0 ,那麼只能放0,同時0的數量加1
如果當前位爲1,那麼我在當前位放0(保證了小於原數),算以當前位爲0開始,後面0和前面0加起來不超過全部1的總狀態
然後這是總共的小於n的狀態數
再算一下n是不是符合條件的,是就加一
還是太弱了寫了一下午。。。。
**/
int solve(int n) {
    if(n <= 0)   return 0;
    int len = 0;
    while(n != 0) {
        bit[++len] = n % 2;
        n /= 2;
    }
    int cnt = 0;
    int zero = 0;
    for(int i = len; i >= 1; i --) {
        if(i == len) {
            for(int j = 1; j <= len - 1; j ++) {
                for(int k = j - 1; k >= j - k; k --) {
                    cnt += dp[1][j][k];
                }
            }
        } else {
            if(bit[i] == 0) {
                zero ++;
                continue;
            }
            else {
                for(int j = i; zero + j >= len - zero - j; j --) {
                    cnt += dp[0][i][j];
                }
            }
        }

    }
    if(count(bit + 1,bit + len + 1,0) >= count(bit + 1,bit + len + 1,1))    cnt ++;
    return cnt;
}


int main() {
//    freopen("in.txt","r",stdin);
    int l,r;
    getdp();
    while(~scanf("%d%d",&l,&r)) {
        printf("%d\n",solve(r) - solve(l - 1));
    }

    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章