在采用穷举法解决问题时,大多数时候可以确定穷举的范围,即待解决问题有明确的区间限制,可以采用循环在这个指定的范围内搜索满足约束条件的解。
【例2】数字方格
有3个方格,每个方格里面都有一个整数a1,a2,a3。已知0<=a1,a2,a3<=n,而且a1+a2是2的倍数,a2+a3是3的倍数,a1+a2+a3是5的倍数。编写一个程序,输入一个n(0 <= n<=100),找到一组a1、a2、a3,使得a1+a2+a3最大。
(1)编程思路。
用3重循环直接对0~n范围内的a1、a2、a3进行穷举。在内循环中检测约束条件((a1+a2)%2==0) && ((a2+a3)%3==0) && ((a1+a2+a3)%5==0)是否满足,若满足,再看是否需要更新max的值(max初值可设置为0)。
(2)源程序及运行结果。
#include <iostream>
using namespace std;
int main()
{
int a1,a2,a3,n,max,x,y,z;
max=0;
cin>>n;
for(a1=0;a1<=n;a1++)
for(a2=0;a2<=n;a2++)
for(a3=0;a3<=n;a3++)
{
if (((a1+a2)%2==0) && ((a2+a3)%3==0) && ((a1+a2+a3)%5==0))
{
if((a1+a2+a3)>max)
{
max=a1+a2+a3;
x=a1; y=a2; z=a3;
}
}
}
cout<<"Max="<<max<<endl;
cout<<"a1="<<x<<",a2="<<y<<",a3="<<z<<endl;
return 0;
}
(3)问题扩展。
上面的程序可以求出a1+a2+a3的最大值,以及达到最大值时a1、a2、a3的取值情况。但实际上,对于给定的n,当a1+a2+a3达到最大值时,a1、a2、a3的取值组合可能有多种。例如,n=5时,a1+a2+a3的最大值为10,达到最大值时,满足要求的a1、a2、a3的取值组合有(1,5,4)、(4,2,4)和(4,4,2)三种。能否对程序进行扩展连营,输出所有的组合情况呢?
为保存所有的组合情况,程序中可以定义一个二维数组。在max更新时,对数组进行更新。
(4)扩展问题的源程序及运行结果。
#include <iostream>
using namespace std;
int main()
{
int a1,a2,a3,n,i,max,cnt;
int a[100][3];
max=0; cnt=0;
cin>>n;
for(a1=0;a1<=n;a1++)
for(a2=0;a2<=n;a2++)
for(a3=0;a3<=n;a3++)
{
&n