2013年6月九度Online Judge程序猿求职及面试月赛 - 题目1:二进制中1的个数

来源:互联网 发布:知乎 比逗 编辑:程序博客网 时间:2024/05/16 00:32

题目1:二进制中1的个数

时间限制:1 秒

内存限制:128 兆

特殊判题:

提交:201

解决:48

题目描述:

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

输入:

输入可能包含多个测试样例。
对于每个输入文件,第一行输入一个整数T,代表测试样例的数量。对于每个测试样例输入为一个整数。
n保证是int范围内的一个整数。

输出:

对应每个测试案例,
输出一个整数,代表输入的那个数中1的个数。

样例输入:
345-1
样例输出:
1232

该题提交的第三次才通过了,最开始采用移位操作,会超时,后来改为查表,第一用C++写的,还是超时,无奈,改为C,通过,代码如下,有注释,这里就不在赘述了。

第一次采用C++移位操作,Time Limit Exceed。

/**作者:齐士垚日期:2013.6.23功能:计算一个数的二进制表示中含有的1的个数语言:   C++ */ #include<iostream>using namespace std;int main() {int i,n,m,count;unsigned int flag;    //尽量减少空间占用,采用unsigned int while(cin>>n) { //扫描案例数目 for(i = 0; i < n; i++) {count = 0;//重置计数器 flag = 1;//标志位,用于逐位判断数字是否为1 cin>>m;//输入待判数据 while(flag) {//循环直到判断完32位 if(m & flag) {//该位为1,计数器增1 count++;}flag <<= 1;//标志位移动 }cout<<count<<endl;//输出计数值 }}return 0;}

第二次还是采用C++,采用查表方式,由于C++的输入输出比较耗时,依然超时,换为C,Accepted,下边直接将C的代码给出。
/**作者:齐士垚日期:2013.6.23功能:计算一个数的二进制表示中含有的1的个数语言:C*/ #include<stdio.h>int main() {unsigned char table[256] = {//查表,表示8位二进制数总共含有1的个数,下标用该二进制数表示 //也可以4位一组,这样可以减小待查数组的大小,不过最后求结果的话,//就麻烦了,有得必有失。 0,1,1,2, 1,2,2,3, 1,2,2,3, 2,3,3,4,1,2,2,3, 2,3,3,4, 2,3,3,4, 3,4,4,5,1,2,2,3, 2,3,3,4, 2,3,3,4, 3,4,4,5,2,3,3,4, 3,4,4,5, 3,4,4,5, 4,5,5,6,1,2,2,3, 2,3,3,4, 2,3,3,4, 3,4,4,5,2,3,3,4, 3,4,4,5, 3,4,4,5, 4,5,5,6,2,3,3,4, 3,4,4,5, 3,4,4,5, 4,5,5,6,3,4,4,5, 4,5,5,6, 4,5,5,6, 5,6,6,7,1,2,2,3, 2,3,3,4, 2,3,3,4, 3,4,4,5,2,3,3,4, 3,4,4,5, 3,4,4,5, 4,5,5,6,2,3,3,4, 3,4,4,5, 3,4,4,5, 4,5,5,6,3,4,4,5, 4,5,5,6, 4,5,5,6, 5,6,6,7,2,3,3,4, 3,4,4,5, 3,4,4,5, 4,5,5,6,3,4,4,5, 4,5,5,6, 4,5,5,6, 5,6,6,7,3,4,4,5, 4,5,5,6, 4,5,5,6, 5,6,6,7,4,5,5,6, 5,6,6,7, 5,6,6,7, 6,7,7,8,};int i,n,m;while(scanf("%d", &n) != EOF) {   //直到待测案例结束 for(i = 0; i < n; i++) {//测试每组数据 scanf("%d", &m);printf("%d\n",table[m & 0xff] + table[(m >> 8) & 0xff] + table[(m >> 16) &0xff] + table[(m >> 24) & 0xff]);//8位一组,求和作为结果 }}return 0;}

下边给出4位一组的代码,待查数组小了,可是时间变长了,因为大数据需要更多地移位操作。

/**作者:齐士垚日期:2013.6.23功能:计算一个数的二进制表示中含有的1的个数语言:C*/ #include<stdio.h>int main() {unsigned char table[16] = {//查表,表示4位二进制数总共含有1的个数,下标用该二进制数表示 0,1,1,2, 1,2,2,3, 1,2,2,3, 2,3,3,4,};int i,n,m;while(scanf("%d", &n) != EOF) {   //直到待测案例结束 for(i = 0; i < n; i++) {//测试每组数据 scanf("%d", &m);printf("%d\n",table[m & 0x0f] + table[(m >> 4) & 0x0f] + table[(m >> 8) &0x0f]+table[(m >> 12) &0x0f]+table[(m >> 16) &0x0f]+table[(m >> 20) &0x0f]+table[(m >> 24) &0x0f]+ table[(m >> 28) & 0x0f]);//4位一组,求和作为结果 }}return 0;}