巧用二进制编程

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

巧用二进制数思想编程方法例谈

浙江慈溪实验中学张利波315300

二进制数在计算机中有着非常重要的意义,在信息学竞赛中,巧妙使用二进制数的特点,可能使程序思路更加简洁明了,解题也变得相当简单,下面列举几个程序来说明。

例1、如图所示为一个城市街道简图,小明从A点出发到达B点。如果在每一个路口只能向右或向上走,问小明可有多少条行走路线?并输出每条路线。

问题分析:该题一般的方法可以用深度优先遍历或广度优

编程呢?根据题意,可以通过以下几个方面进行分析:

①行走方向只有两种向右走或向上走,那么我们不妨

用0表示向上走,1表示向左走;②根据路径从A点到B

点,不论走哪条路径,走的步数总是固定的,如图中就是7步,因此,我们可以确定二进制数的位数是7位;③根据行走方向,用“1”表示向右走,据图向右走的步数为4,用二进制数表示又产生一个约束条件,7位二进制数中的“1”的个数为4,同理,“0”的个数为3。

根据以上分析,原题即转换成对7位二进制数的筛选,范围在(0001111)2——(1111000)2之间,且分离各位数字,相加为4,符合上述条件的,即为可以行走的一条路线,要统计所有可行走路线,只要对每个符合条件的线路数量累加即可。参考程序中避免了十进制数转换成二进制数的操作,采用穷举所有7位的二进制数并对此进行筛选完成。参考程序如下。

#include"stdafx.h"

#include

#include

using namespace std;

int _tmain(int argc, _TCHAR* argv[])

{

time_t begin,end;

begin=clock();

int x;

int total=0;

for(int i=0X0000000F;i<0X00000079;i++)

{

int x=i;

//求i的二进制码中有多少个

x= (x & 0X55555555) + ((x >> 1) & 0X55555555);

x= (x & 0X33333333) + ((x >> 2) & 0X33333333);

x= (x & 0X0F0F0F0F) + ((x >> 4) & 0X0F0F0F0F);

x= (x & 0X00FF00FF) + ((x >> 8) & 0X00FF00FF);

x= (x & 0X0000FFFF) + ((x >> 16) & 0X0000FFFF);

if (x==4)

{

for (int j=6;j>=0;--j)

{

if (((1<

cout<<"1";

else

cout<<"0";

}

cout<

total++;

}

}

cout<

end=clock();

cout<

}

例2、如下图,有一个无穷大的栈S ,在栈的右边排列着1,2,3,4,5共五个车厢。其中每个车厢可以向左行走,也可以先

进栈S 让后面的车厢通过。现已知第一个到达出口的是3号车厢,请写出所有可能的到达出口的车厢排列总数,并输出每种排列。(源自第八届信息学初赛普及组问题求解)

问题分析:这是一例典型的栈应用题,主要考察栈“先进后出”特点,如果用常规办法,如递归,也可能造成遗漏,用非递归办法则更为复杂。根据题意,我们可以通过以下几个方面进行分析:

①栈的操作只有两类:进栈和出栈,那么就可以用二进制数0、1表示,用“1”表示进栈,“0”表示出栈;②每个车厢经过栈操作(进栈出栈),如果车厢直接向左行走,可以理解成进栈后马上出栈,这样就可以把5个车厢的操作化解成10个动作,用10个二进制位数来表示;③根据栈操作,出栈必在进栈之后,则对应二进制数“1”的个数必不小于“0”个数;④题意中要求第一个到达出口的是3号车厢,可以确定二进制数的高4位数字为“1110”,表示1,2,3车厢进栈后,首个出栈车厢为第3个车厢,这样数据范围由原来10位缩小至低6位;⑤此外由题意不难发现,该6位上的二进制数字,含“1”的个数为2个,因此可以进一步框定数据范围在(001010)2——(110000)2,⑥最后一次操作不可能是进栈操作,因此数据最低位不能为1,即只能为偶数。参考程序如下。 #include "stdafx.h"

#include

出口← ←

S ↓

#include

using namespace std;

int _tmain(int argc, _TCHAR* argv[])

{

time_t begin,end;

begin=clock();

int total=0,x;

for(int i=0X0000000A;i<0X00000031;++i)

{

if((i&1)==0)

{

x=i;

x= (x & 0X55555555) + ((x >> 1) & 0X55555555);

x= (x & 0X33333333) + ((x >> 2) & 0X33333333);

x= (x & 0X0F0F0F0F) + ((x >> 4) & 0X0F0F0F0F);

x= (x & 0X00FF00FF) + ((x >> 8) & 0X00FF00FF);

x= (x & 0X0000FFFF) + ((x >> 16) & 0X0000FFFF);

if(x==2)

{

total++;

cout<<"1110";

for(int j=5;j>=0;--j)

{

if(((1<

cout<<"0";

else

cout<<"1";

}

cout<

}

}

}

end=clock();

cout<

return 0;

}

通过以上两个程序,我们大致了解用二进制数编程的方法,那么适用该方法时,程序描述有哪些明显特点呢?下面是笔者归纳的一些特点:

相关文档
最新文档