HDU 2502 月之数【巧用位运算 + 快速幂】

来源:互联网 发布:注册六西格玛黑带 知乎 编辑:程序博客网 时间:2024/05/18 06:25

月之数

Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 11254 Accepted Submission(s): 6594

Problem Description

当寒月还在读大一的时候,他在一本武林秘籍中(据后来考证,估计是计算机基础,狂汗-ing),发现了神奇的二进制数。
如果一个正整数m表示成二进制,它的位数为n(不包含前导0),寒月称它为一个n二进制数。所有的n二进制数中,1的总个数被称为n对应的月之数。
例如,3二进制数总共有4个,分别是4(100)、5(101)、6(110)、7(111),他们中1的个数一共是1+2+2+3=8,所以3对应的月之数就是8。

Input

给你一个整数T,表示输入数据的组数,接下来有T行,每行包含一个正整数 n(1<=n<=20)。

Output

对于每个n ,在一行内输出n对应的月之数。

Sample Input

3
1
2
3

Sample Output

1
3
8

Source

《ACM程序设计》短学期考试_软件工程及其他专业

题意: 让你求n位二进制的所有数中,1的个数

分析: 第一个方法,我们可以找规律,发现n为的二进制中第一位都为1,我们把当n = 4时的情况写一下,就能找到规律了,分别如下:

 1000  1001  1010  1011  1100  1101  1110  1111 我们可以发现,除了首位1之外,每位上都有2^(n-2)个1,一共有n-1位 所以答案应该为    pow(2,n-1) + (n-1)*pow(2,n-2)

第二种方法,我们可以利用位运算中的__builtin_popcount(i),可以直接计算出i的二进制中1的个数

快速幂代码

#include <iostream>#include <cmath>using namespace std;int main(){    int i;cin>>i;    while(i--){        int n,res = 0;        cin>>n;        res = pow(2,n - 1) + (n - 1) * pow(2, n - 2);        cout<<res<<endl;    }    return 0;}

位运算代码

#include <bits/stdc++.h>using namespace std;int get(int x) {    int sum = 0;    x--;    for(int i = 1<<x;i < 1<<x+1;i++) {        sum += __builtin_popcount(i);    }    return sum;}int main() {    int T;cin>>T;    while (T--) {        int n;cin>>n;        cout<<get(n)<<endl;    }    return 0;}
  • 如有错误或遗漏,请私聊下UP,thx
原创粉丝点击