GCC有一个叫做__builtin_popcount的内建函数,它可以精确的计算1的个数。尽管如此,不同于__builtin_ctz,它并没有被翻译成一个硬件指令(至少在x86上不是)。相反的,它使用一张类似上面提到的基于表的方法来进行位搜索。这无疑很高效并且非常方便。
为了在 VC 上实现 __builtin_popcount (unsigned u) 的功能,自己写了两个函数,分别是 popcnt (unsigned u), popcount (unsigned u) 。
说到底,这个函数到底有什么实际用处呢?当然有了,使用一个二进制数字表示一个集合的时候,枚举一个组合(子集),需要判断这个数字里面的 1 的个数是不是和子集的大小相等。这种方法通常是属于暴力法,如果不是使用二进制数字表示集合,很可能就计算超时了。
Given a matrix of size M*N, the elements of which are integer numbers from -10 to 10. You task is to go from
the top-left corner (1, 1) to the bottom-right corner (M, N). You can only move right or down, and you can
not go out of the matrix. The number in the grid you passed must be picked. The sum of numbers you picked must
be positive and as minimal as possible.
The input contains several test cases.
The first line of each test case are two integer numbers M, N (2<=M<=10, 2<=N<=10), indicating the number
of rows and columns of the matrix. The following M lines, each contains N integer numbers.
For each test case, output the sum of numbers you picked on a single line. If you can't get a positive sum,
output -1.
Run ID User Name Problem Language Status Run Time Run Memory Submit Time
84848 rappizit 1158 C++ Accepted 0.01 sec 260 KB 2007-09-17 13:38:57
经测试,该函数的速度是 G++ 的一半,所以有理由认为 G++ 保存的表的大小是 65536 的(或者使用汇编)。但是不可能在自己的代码里面加上那么一大段数据吧?权衡一下,表的大小设为 256 是适当的,可以在 VC 里面使用以下代码。
char
poptable [
256
]
=
{
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
};
unsigned __builtin_popcount (unsigned u)
{
return
poptable [u
&
0xFF
]
+
poptable [(u
>>
8
)
&
0xFF
]
+
poptable [(u
>>
16
)
&
0xFF
]
+
poptable [(u
>>
24
)
&
0xFF
];
}