poj 3252 Round Number

来源:互联网 发布:office2003是什么软件 编辑:程序博客网 时间:2024/06/11 02:30

题目不是很难,不过因为一个细节贡献了两次wa(在计算[0, 0]上的round numbers时答案应该是0,结果算成了1)

思路就是[a, b] 上的答案等于[0, b] - [0, a - 1]。

在计算[0, k]上的round numbers时,先求位数比k的二进制小的,这些数肯定比k小,所以0和1可以任意放,用排列组合的方法很容易算。然后求和k的二进制位一样长的,从k的二进制的最高位往下求(最高位除外),遇到1就假设把这个1换成0,那么后面的数组不管放几,肯定比k小,这样就可以用排列组合的方法求这种情况下的round numbers了,扫完所有二进制位就可以了。

如果k的二进制位中0的数目本来就多余或等于1的数目,答案+1。

/* * Author: stormdpzh * POJ: 3252 Round Numbers * Time: 2012/4/28 21:18:29 */#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cmath>#include <vector>#include <queue>#include <stack>#include <set>#include <algorithm>#include <functional>#define sz(v) ((int)(v).size())#define rep(i, n) for(int i = 0; i < n; i++)#define repf(i, a, b) for(int i = a; i <= b; i++)#define out(n) printf("%d", n)#define wh(n) while(scanf("%d", &n) != EOF)#define whz(n) while(scanf("%d", &n) != EOF && n != 0)#define int64 long longusing namespace std;int C[35][35];      //C[i][j], C(i, j);int bin[35];        //binary numberint len;            //length of binary numbervoid getC(){    C[0][0] = 1;    repf(i, 1, 34) {        repf(j, 0, i) {            if(j == 0 || i == j)                C[i][j] = 1;            else                C[i][j] = C[i - 1][j - 1] + C[i - 1][j];        }    }}void getBin(int num){    len = 0;     while(num) {        bin[len++] = num & 1;        num = num >> 1;    }}//solve(k): calculate round numbers of [0, k]int solve(int key){       if(key <= 1)        return 0;        int res = 0;    memset(bin, 0, sizeof(bin));    getBin(key);        for(int i = 1; i < len; i++) {        repf(j, (i >> 1) + (i & 1), i - 1) {            res += C[i - 1][j];        }    }    int zero = 0;    int tmp = (len >> 1) + (len & 1);    for(int i = len - 2; i >= 0; i--) {        if(bin[i] == 1) {            repf(j, max(tmp - zero - 1, 0), i)                res += C[i][j];        }        else            zero++;    }    if(zero >= (len >> 1) + (len & 1))        res++;        return res;}int main(){    int start, finish;    getC();     while(scanf("%d%d", &start, &finish) != EOF) {        printf("%d\n", solve(finish) - solve(start - 1));    }    return 0;}


原创粉丝点击