基于已有知识进行答案猜测的一种问题求解策略
从可能的集合中一一列举各元素
根据所知道的知识,给一个猜测的答案
枚举算法
对问题可能解集合的每一项
根据问题给定的检验条件判定哪些是成立的
使条件成立的即是问题的解
判断猜测的答案是否正确
进行新的猜测:有两个关键因素需要注意
1、猜测的结果必须是之前没出现过的
2、猜测过程要及早排除错误的答案
给出解空间,建立简洁的数学模型
减少搜索的空间
采用合适的搜索顺序
eg 1:小于N的最大素数
#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;
//求小于N的最大素数
//最小的素数是2,之后的偶数不可能是素数,之后的素数不能被之前的素数整除
int main()
{
vector<int> vPrimeNumber;
int n;
int maxFactor;
bool isPrimeNumber = true;
while(cin>>n)
{
if(n < 2 )
break;
if(n == 2)
maxFactor = 2;
vPrimeNumber.push_back(maxFactor);
for(int i = 1;2*i +1 < n;i++)
{
for(int j= 0; i<vPrimeNumber.size();i++)
{
if((2*i+1)%vPrimeNumber[j] == 0)
{
isPrimeNumber = false;
break;
}
}
if(isPrimeNumber)
{
maxFactor = 2*i+1;
vPrimeNumber.push_back(maxFactor);
}
}
char temp[200];
sprintf(temp,"小于 %d 的最大素数为 %d \n",n,maxFactor);
printf("%s",temp);
}
return 0;
}
eg 2:熄灯问题
bool Guess()
{
for(int i = 1; i< 5 ;i++)
{
for(int j =1; j<7 ;j++)
{
PRESS[i+1][j] = (PUZZLE[i][j] + PRESS [i][j-1] + PRESS[i][j] + PRESS[i][j+1] + PRESS[i-1][j])%2 ;
}
}
for(int i = 1;i<=6;i++)
{
if((PRESS[4][i] + PRESS[5][i-1]+PRESS[5][i]+PRESS[5][i+1])%2 != PUZZLE[5][i] )
return false;
}
return true;
}
void Enumerator()
{
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()
{
for(int i=0;i<=7;i++)
{
PRESS[0][i] = 0;
}
for(int i=1 ;i<=5;i++ )
{
PRESS[i][0]=PRESS[i][7] = 0;
}
int N;
cin>>N;
for(int i = 0; i<N;i++)
{
for(int j=1;j<=5;j++)
{
for (int k=1;k<=6;k++)
{
scanf("%d",&PUZZLE[j][k]);
}
}
}
Enumerator();
printf("-----------------------------\n");
for(int j =1 ;j<= 5;j++)
{
for (int k = 1; k <= 6;k++)
{
printf("%d ",PRESS[j][k]);
}
printf("\n");
}
return 0;
}