「算法」北京大学算法基础(1)—枚举-2开6次方是多少

基于已有知识进行答案猜测的一种问题求解策略。

例如:求小于N的最大素数

找不到一个数学公式,使得根据N就可以计算出这个素数

思考:N-1是素数吗?N-2是素数吗?……N-k是素数吗?

—>判断N-k是否是素数问题,转化为求小于N-k的全部素数。

枚举的思想:

猜测

枚举算法

对问题可能解集合的每一项

根据问题给定的检验条件判定哪些是成立的

使条件成立的即是问题的解

枚举过程

判断猜测的答案是否正确

2是小于N的最大素数吗?

进行新的猜测:有两个关键因素要注意

猜测的结果必须是前面的猜测中没有出现过的.每次猜测是素数一定比已经找到的素数大

猜测的过程中要及早排除错误的答案.除2之外,只有奇数才可能是素数

枚举中三个问题:

给出解空间,建立简洁的数学模型

减少搜索的空间

采用合适的搜索顺序

熄灯问题:

有一个由按钮组成的矩阵,每行有6个按钮,共5行。每个按钮位置上有一盏灯。当按下一个按钮后,该按钮以及周围位置(上边,下边,左边,右边)的灯都会改变一次。(如果灯原来是点亮的,就会被熄灭如果灯原来是熄灭的,则会被点亮)

对矩阵中的每盏灯设置一个初始状态。请你写一个程序,确定需要按下哪些按钮,恰好使得所有的灯都熄灭。

输入:

·第一行是一个正整数N,表示需要解决的案例数

·每个案例由5行组成,每一行包括6个数字

·这些数字以空格隔开,可以是0或1

·0表示灯的初始状态是熄灭的·1表示灯的初始状态是点亮的

输出:

·对每个案例,首先输出一行,输出字符串“PUZZLE#m”,其中m是该案例的序号

·接着按照该案例的输入格式输出5行

·1表示需要把对应的按钮按下

·0表示不需要按对应的按钮

·每个数字以一个空格隔开

思考

:枚举每个按钮的开和关,需要2的30次方。如何减少枚举状态数?基本思路,局部状态确定。每一行的状态都受下面一行的影响。第一行状态固定后,需要熄灭第二行的等灯,第2行的开关起作用后,为了熄灭第2行的灯,第3行的合理开关状态就也是唯一的。以此类推,最后一行的开关状态也是唯一的。一只要第1行的状态定下记作A,那么剩余行的情况就是确定唯一的了。推算出最后一行的开关状态,然后看看最后一行的开关起作用后,最后一行的所有灯是否都熄灭。

·如果是,那么A就是一个解的状态

·如果不是,那么A不是解的状态,第1行换个状态重新试试

所以需要枚举第一行(2的6次方)状态或列。可以使用6层循环。也可以看成二进制状态码。同时我们可以扩充矩阵范围,这样点击角处的按钮情况就便于操作了。5*6矩阵阔成6*8矩阵。

puzzle是矩阵初始状态,press是点击状态,是否点按下一行的按钮,就要判断上一行按钮的状态,上一行按钮状态受初始状态和四周按钮点按的影响。

press[r+1][c]=(puzzle[r][c]+press[r][c-1]+press[r][c]+press[r][c+1]+press[r-1][c])%2

0

# include

int puzzle[6][8], press[6][8];

bool guess(){

int c,r;

for(r=1;r<5;r++) for(c=1;c<7;c++)

press[r+1][c]=(puzzle[r][c]+press[r][c]+press[r-1][c]+press[r][c-1]+press[r][c+1])%2; //根据前一行状态,判断本行是否按

for(c=1;c<7;c++)

if((press[5][c-1]+press[5][c]+press[5][c+1]+press[4][c])%2!=puzzle[5][c])

return(false); //判断最后一行状态,是否全部熄灭

return(true);

}

void enumerate (){ //循环猜的过程

int c; bool success;

for(c=1;c<7;c++)

press[1][c]=0;

while(guess()==false){

press[1][1]++; c=1;

while(press[1][c]>1){

press[1][c]=0;

c++;

press[1][c]++;

}

return;

}

int main(){

int cases,i,r,c; scanf("%d",&cases);

for(r=0;r<6;r++)

press[r][0]=press[r][7]=0;

for(c=1;r<7;r++)

press[0][c]=0;

for(i=0;i

for(r=1;r<6;r++)

for(c=1;c<7;c++)

scanf("%d",&puzzle[r][c]);

enumerate();

printf("PUZZLE #%d\n",i+1);

for(r=1;r<6;r++){

for(c=1;c<7;c++)

printf("%d",press[r][c]);

printf("\n");

}

}

return 0;

}

影像三次元

ogp光学影像测量机

影像测量系统

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至举报,一经查实,本站将立刻删除。