klion26
klion26's blog
C++博客
|
首页
|
发新随笔
|
发新文章
|
联系
|
聚合
|
管理
随笔:71 文章:0 评论:17 引用:0
POJ 2453 疯狂的位运算
这题是宁波区域赛的热省赛中的一题……
后来偶然发现时POJ上的,而且有人用位运算搞过了,于是就去学位运算,通过Matrix67大牛的三篇文章学的,第四篇还没看,(想看的可以去搜下Matrix67或者去我前面的文章找下,应该是sgu那篇,可以找到链接)
这题可以这么想,比如原数x=0101110的下一个是01100011,你可以这样想,以要比原数大,必须把原数的最右边的一段1(连续的,如果只有一个的,就是一个)变成0,把这段1的右边的第一个0变成1,然后再在所得的数的最右边补1,知道1的位数一样。
这样的话,我们就可以这样做了
设原数为x
然后t = x + (x & -x);//(x & -x) 取x的最右边的一个1,因为"把原数的最右边的一段1变成0"可以加上最右边一个1
接下来就是补1的过程了,当然可能不用补
好吧我们用一个函数得到x(10进制)在2进制表示下的1的个数(如果有看不懂的,建议先看下Matrix67大牛的位运算在看,当然到那个时候基本你自己也可以写了,不必要看我的了,呵呵)
函数如下
get
1
int
get
(
int
n)
2
{
3
n
=
(n
&
0x55555555
)
+
((n
>>
1
)
&
0x55555555
);
4
n
=
(n
&
0x33333333
)
+
((n
>>
2
)
&
0x33333333
);
5
n
=
(n
&
0x0F0F0F0F
)
+
((n
>>
4
)
&
0x0F0F0F0F
);
6
n
=
(n
&
0x00FF00FF
)
+
((n
>>
8
)
&
0x00FF00FF
);
7
n
=
(n
&
0x0000FFFF
)
+
((n
>>
16
)
&
0x0000FFFF
);
8
return
n;
9
}
这样我们就基本是完成了。具体代码如下,个人建议先自己想,实在想不出来之后再看我的代码
CODE
1
/**/
/*
2
ID:Klion
3
PROG:POJ_2453
4
LANG:C++
5
*/
6
#include
<
iostream
>
7
using
namespace
std;
8
int
get
(
int
n)
9
{
10
/**/
/*
11
这里是错的,因为这样的话,会错位,具体可以自己
12
手动算一下,可以用这个数11010011(211)
13
n = (n & 0xAAAAAAAA) + ((n >> 1) & 0xAAAAAAAA);
14
n = (n & 0xCCCCCCCC) + ((n >> 2) & 0xCCCCCCCC);
15
n = (n & 0xF0F0F0F0) + ((n >> 4) & 0xF0F0F0F0);
16
n = (n & 0xFF00FF00) + ((n >> 8) & 0xFF00FF00);
17
n = (n & 0xFFFF0000) + ((n >> 16) & 0xFFFF0000);
18
*/
19
n
=
(n
&
0x55555555
)
+
((n
>>
1
)
&
0x55555555
);
20
n
=
(n
&
0x33333333
)
+
((n
>>
2
)
&
0x33333333
);
21
n
=
(n
&
0x0F0F0F0F
)
+
((n
>>
4
)
&
0x0F0F0F0F
);
22
n
=
(n
&
0x00FF00FF
)
+
((n
>>
8
)
&
0x00FF00FF
);
23
n
=
(n
&
0x0000FFFF
)
+
((n
>>
16
)
&
0x0000FFFF
);
24
return
n;
25
}
26
int
main(
void
)
27
{
28
int
x;
29
int
t,b,c;
30
while
(scanf(
"
%d
"
,
&
x),x)
31
{
32
c
=
x
&
-
x;
33
t
=
x
+
c;
34
b
=
get
(x)
-
get
(t);
35
t
=
t
|
((
1
<<
b)
-
1
);
36
printf(
"
%d\n
"
,t);
37
}
38
return
0
;
39
}
40
发表于 2010-05-24 19:31
Klion
阅读(324)
评论(0)
编辑
收藏
引用
所属分类:
POJ
只有注册用户
登录
后才能发表评论。
【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态!
相关文章:
顶嵌杯--D 序列
顶嵌杯--C 字符串替换
顶嵌杯--B 取模
顶嵌杯--A 分数加减法
POJ 1273 网络流入门题 ---EK算法
POJ 1014 && 1742 多重背包的O(VN)解法
POJ 3070
POJ 1661 Help Jimmy
POJ_3321 树状数组
POJ 3067 树状数组
网站导航:
博客园
IT新闻
BlogJava
博问
Chat2DB
管理
<
2010年8月
>
日
一
二
三
四
五
六
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
(1)
给我留言
查看公开留言
查看私人留言
随笔分类
(99)
DP(7)
(rss)
Linux学习之路(11)
(rss)
POJ(18)
(rss)
USACO(27)
(rss)
计算机专业(3)
(rss)
计算几何
(rss)
数据结构&字符串(14)
(rss)
数学(8)
(rss)
搜索(4)
(rss)
贪心(1)
(rss)
图论(4)
(rss)
杂(2)
(rss)
随笔档案
(71)
2010年12月 (7)
2010年11月 (11)
2010年9月 (6)
2010年8月 (12)
2010年7月 (12)
2010年6月 (6)
2010年5月 (15)
2010年4月 (2)
好友链接
我的独立域名
我的独立域名
搜索
最新评论
1. re: SQL Server 2005端口号设置
在程序中的数据库连接字符串也应该做相应的更改,怎么操作啊?
--peijian
2. re: SQL Server 2005端口号设置
如果是在本机,客户端IP还是写localhost吗?
--的
3. re: VMware 安装RedHat9时光盘无法挂载的问题[未登录]
嗯 收获了 谢谢
--jz
4. re: Ubuntu死机那点事
确实有用,我用到第3点,就可以了。
谢谢!
--Annie
5. re: POJ_1195 二维树状数组
@yp
能有这效果,我表示非常高兴
--klion26
阅读排行榜
1. Ubuntu死机那点事(4778)
2. SQL Server 2005端口号设置(4692)
3. POJ 1014 && 1742 多重背包的O(VN)解法(2928)
4. 三种简单博弈问题的简单介绍(2862)
5. HDU_1907&2509 博弈(2279)
评论排行榜
1. SQL Server 2005端口号设置(6)
2. 三种简单博弈问题的简单介绍(2)
3. 回归CPP Blog(2)
4. POJ_1195 二维树状数组(2)
5. 《自己动手写操作系统》第一步(2)