穷举法ppt课件

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

scanf(“%d,%d”,&n,&k);
for(i=1;i<=n;i++)
scanf(“%d”,&a[i]);
for(i=0;i>=n;i++) b[i]=1;
cmin=1000000;
while(b[0]==1)
{
for(i=1;i<=k;i++)
____s_[i_]_=_0_; ________;
4
例2.除法运算(NOIP1995初中组复赛第一题) 设有下列的除法算式:
请根据上述算式中的信息求出被除数和除数。 分析:设除数为x,被除数为y,由算式信息可知:10<=x<=99, 1000<=y<=9999,且8*x<=99,9*x>=100。因此,我们可选择枚举除 数,而被除数则可按公式y=809*x+1计算得出。
8
int link[6,2]={{1,2},{1,4},{2,5},{4,7},{5,8},{7,8}};
int b[9];
main()
{
b[1]=2;b[3]=8;b[6]=1;b[8]=7;
try;
b[1]=7;b[2]=1;b[6]=8;b[8]=2;
try;
}
void print;
{
printf(“%4d\n”,b[1]);
printf(“%d”,d[i]);
}
13
穷举法的基本思想: 穷举也叫枚举,它的基本思想是先依据题目的部分条件来确定答案
的大致范围(可能解),然后在此范围内用其余的条件对所有可能解进 行一一验证,删去那些不符合条件的解,剩下符合条件的解就是整个问 题的解
1
例1.找完全数 古希腊人认为因子的和等于它本身的数是一个完全数(自身因子除外)。 例如28的因子是1、2、4、7、14,且1+2+4+7+14=28,则28是一个完 全数。编写一个程序求2~10000内的所有完全数。
printf (“%d,%d”,y,x); /*验证,如果满足要求,则输出* }
}
运行结果:
9709 12
6
练习:1.求出所有满足下列条件的二位数:将此二位数的个位数字与十位数 字进行交换,可得到一个新的二位数,要求新数与原数之和小于100。 程序要求:每行输出6个满足条件的数。 算法提要:分解每一个二位数,然后重新组成一个新数,当满足条件时,用计
程序说明: 数组: a[1],a[2],...a[n]存放原数 s[1],s[2],...,s[k]存放每个部分的和 b[1],b[2],...,b[n]穷举用临时空间 d[1],d[2],...,d[n]存放最佳方案
11
main()
{
int i,j,n,k,sum,a[101],b[100],s[31];
if (__k_%__6_=_=0___) printf(“\n”);
}
}
}
7
例5.方格填数 如下图所示的八个格子中填入1至8八个数字,使得相邻的和对角ຫໍສະໝຸດ 线的数字之差不为1。编程找出所有放法。
b1 b2 b3 b4 b5 b6 b7
b8
分析:由题意可知,放入b3,b6这两个格子中的数,必须和六 个数不连续,仅可以和一个数是连续的,这样的数只能是1和8。 因此,b1,b3,b6,b8这四个格子中数的放法可以先确定下来: 2,8,1,7或7,1,8,2。接着,我们只需枚举b2、b4、b5 三个变量,范围都是3至6,而b7可通过计算来得到。
for(i=1;i<=n;i++) __s_[b_[_i]_]_=s_[_b_[i_]]_+_a[_i_];__;
sum=0;
for(i=1;i<k;i++)
for (__j_=i_+_1;_j_<=_k_;j_+_+__)
sum=sum+(s[i]-s[j])*(s[i]-s[j]);
12
if (____cm__in_>s_u_m____)
穷举也叫枚举它的基本思想是先依据题目的部分条件来确定答案的大致范围可能解然后在此范围内用其余的条件对所有可能解进行一一验证删去那些不符合条件的解剩下符合条件的解就是整个问11例1
穷举法
在程序设计中,我们经常需要根据给定的一组条件求满足条件的解。 如果问题的解可以用公式,或者按一定的规则、规律求出,那么就可以很 容易地写出相应的程序。但是对于许多问题,我们都难以找到明确的公式 和计算规则,在这种情况下,我们可以利用计算机高速运算的特点,用穷 举法来解。
5
main()
{
int x,y;
for (x=10;x<=99;i++) /*枚举除数x,范围是10~99*/
{
y=809*x+1;
if (y>9999) break; /*计算出被除数y*/ if (__y>_=_1_00_0__&_&__8_*_x_<=_9_9__&_&__9_*x_>_=_10_0___)
printf(“%2d,%2d%2d\n”,b[2],b[3],b[4]);
printf(“%2d%2d%2d\n”,b[5],b[6],b[7]);
printf(“%4d\n”,b[8]);
}
9
void try
{
for (b[2]=2;b[2]<=6;b++)
for(b[4]=3;b[4]<=6;b++)
if (b[2]!=b[4])
b1 b2 b3 b4 b5 b6 b7
b8
for(b[5]=3;b[5]<=6;b++;)
if (b[5]!=b[2] && b[5]!=b[4])
{ b[7]=18-b[2]-b[4]-b[5];
if (choose) print;
}
int choose
}
{
int i,x;
link[6,2]={{1,2},{1,4},{2,5},{4,7},{5,8},{7,8}};
x=0;
for (i=0;i<=5;i++)
if (abs(b[link[i,0]]-b[link[i,1]])==1)
return(x);
return(1);
}
10
练习:2.将n个整数分成k组(k≤n,要求每组不能为空),显然这k个部分均可 得到一个各自的和s1,s2,……sk,定义整数P为: P=(S1-S2)^2+(S1一S3)^2+……+(S1-Sk)^2+(s2-s3)^2+……+(Sk-1Sk)^2 问题求解:求出一种分法,使P为最小(若有多种方案仅记一种)
{
cmin=sum;
for (i=1;i<=n;i++)
d[i]=b[i];
}
j=n;
while( _b_[_j_]=_=_k_ )
j=j-1;
b[j]=b[j]+1;
for(i=j+1;j<=n;j++)
___b_[i_]=_1_; ____;
}
printf(“%40d”,cmin);
for(i=1;i<=n;i++)
数器来统计个数。
main()
{
int k,i,j,x;
k=0;
for(___i=_1_0_;i_<=_9_9_;i_+_+ ____)
{
x=__i_%__10____;
y=__i_/_1_0____;
j=x*10+y; if (___i +_j_<_1_0_0_______)
{
k=k+1;
printf(“%4d”,i);
{
s=0;
for(b=1; b<=a/2;b++) /*分解因子并求出因子和*/
if (a % b==0)
s=s+b;
if (a==s) /*验证,如果数a满足条件,则输出*/
printf(“%d”, a);
}
} 运行结果:
6 28 496 8128
3
从上例可知,穷举法是一种比较笨拙的算法,因为它需要列举出许多个可能解来 一一验证,程序往往需要运行很长时间,效率较低。但是,穷举法也有自己的优 点,它思路简单,容易编写程序,只要时间足够,穷举法能够很容易地求出问题 的全部正确解。 针对穷举法效率较低的缺点,在设计穷举算法时,我们必须注意以下二点: ①考虑枚举变量一定要慎重,枚举变量应尽量少,尽量通过计算而不是枚举来确 定变量。 ②枚举前应尽可能多地将不符合条件的情况预先排除,以缩小枚举范围。
分析: 1.本题只需一个枚举变量a即可,它的范围是2~10000; 2.验证完全数的条件是:所有因子的和等于该数据本身; 3.找出所有因子、并求出因子和是关键的一步,可采用循环完成分解因
子和求因子和。
2
main()
{
int a,b,s;
for( a=2;a<=10000;a++) /*枚举a,范围2~10000*/
相关文档
最新文档