穷举算法c
A. c语言能给个穷举、迭代、递推的举例(要有分析)。。。
穷举的意思能简单, 就是'一个个猜过去'
比如要破解一个8位数的密码, 就是从00000000到99999999的全部数字一个个试过去
这点数字对现在的计算机来说几乎不要时间
迭代是指循环运算, 比如
for ( int i = 0; i < 99999999; ++i) 这个循环就叫做迭代
至于递推, 以下抄自网络
递推算法是一种用若干步可重复的简运算(规律)来描述复杂问题的方法. 递推是序列计算机中的一种常用算法。它是按照一定的规律来计算序列中的每个项,通常是通过计算机前面的一些项来得出序列中的指定象的值。其思想是把一个复杂的庞大的计算过程转化为简单过程的多次重复,该算法利用了计算机速度快和不知疲倦的机器特点。
植树节那天,有五位同学参加了植树活动,他们完成植树的棵树都不相同。问第一位同学植了多少棵时,他指着旁边的第二位同学说比他多植了两棵;追问第二位同学,他又说比第三位同学多植了两棵;... 如此,都说比另一位同学多植两棵。最后问到第五位同学时,他说自己植了10棵。到底第一位同学植了多少棵树?
分析:设第一位同学植树的棵树为a1,欲求a1,需从第五位同学植树的棵数a5入手,根据“多两棵”这个规律,按照一定顺序逐步进行推算:
(1) a5=10;
(2) a4=a5+2=12;
(3) a3=a4+2=14;
(4) a2=a3+2=16;
(5) a1=a2+2=18;
递推算法以初始(起点)值为基础,用相同的运算规律,逐次重复运算,直至运算结束。这种从“起点”重复相同的方法直至到达一定“边界”,犹如单向运动,用循环可以实现。递推的本质是按规律逐次推出(计算)先一步的结果。
B. C语言 穷举法
#include <stdio.h>
void main()
{
int a[100]={0};
int i,j,k,m,n=0,z;
printf("输入数字,每次回车为一个,以-1为结束数字\n");
for(i=0;i<100;i++)
{
scanf("%d",&a[i]);
n++;
if(a[i]==-1)
{
break;
}
}
for(i=0;i<n-1;i++)
{
for(j=0;j<n-2-i;j++)
{
if(a[j]>a[j+1])
{
k=a[j];
a[j]=a[j+1];
a[j+1]=k;
}
}
}
printf("排序后的数字是:\n");
for(i=0;i<n-1;i++)
printf("%d\n",a[i]);
printf("请输入要插入的数字");
scanf("%d",&m);
for(i=0;i<n-1;i++)
{
if(a[i]<=m && a[i+1]>m)
{
z=i;
break;
}
else
{
z=-2;
}
}
if(z>=0)
{
for(i=n-1;i>z;i--)
{
a[i+1]=a[i];
}
a[z+1]=m;
}
if(z==-2)
{
a[n]=m;
}
for(i=0;i<n;i++)
{
printf("%d\n",a[i]);
}
}
C. c语言的穷举法的背包问题
根据题目c1,c2是一组01组合的数组,也就是2个n位2进制数。
所以我的代码逻辑就是,c1,c2初值分别是00000....以及111111....,之后循环执行c1+1;c2-1(2进制加减运算),最大执行次数2的n次方-1(n位2进制数最大数)
代码实现功能,穷举所有可能方案,返回:第一个/最后一个找到的可行方案。
函数intqj(BAGc1,BAGc2,intn,int*bws,intflag);
当flag=1返回第一个可行方案,flag=0查找所有方案并返回最后一个可行方案
我测试时,flag传值0,需要自己改!!
由于迭代顺序,同样实验数据,返回的结构和你案例结构不一样,我在下图标注了。
#include<stdio.h>
#include<math.h>
#include<malloc.h>
#include<string.h>
typedefstructbag
{
intbweight;
char*books;
}BAG;
intqj(BAGc1,BAGc2,intn,int*bws,intflag);//穷举所有n位2进制组合,返回最后一个可行方案(可能有多个方案)。
//参数:c1背包1,c2背包2,n书本个数,bws所有书本重量,标识:flag=1找到第一个可行方案截止,flag=0查找所有方案
intcheckOverLoad(BAGc1,BAGc2,int*bws,intn);
voidadd2(char*nums);//2进制字符串+1运算
voidsub2(char*nums);//2进制字符串-1运算
intmain()
{
BAGc1,c2;
inti,n,*bws,sum=0;
printf("请输入两个背包的最大载重:
");
scanf("%d%d",&c1.bweight,&c2.bweight);
printf("请输入书本的数量:
");
scanf("%d",&n);
c1.books=(char*)malloc(sizeof(char)*(n+1));
c2.books=(char*)malloc(sizeof(char)*(n+1));
c1.books[0]=0;
c2.books[0]=0;
bws=(int*)malloc(sizeof(int)*n);
while(1)
{
sum=0;
printf("请输入每本书的重量:
");
for(i=0;i<n;i++)
{
scanf("%d",&bws[i]);
sum+=bws[i];
}
if(sum<=c1.bweight+c2.bweight)
break;
else
printf("书本重量和超过背包负重和!请重新输入
");
}
qj(c1,c2,4,bws,0);
//------------------------------打印结果-----------------------------
printf("
输出:
");
printf("book");
for(i=0;i<n;i++)
printf("%d",bws[i]);
printf("
");
printf("c1%s
",c1.books);
printf("c2%s
",c2.books);
}
intqj(BAGc1,BAGc2,intn,int*bws,intflag)//穷举所有n位二进制数,
{
inti,max=(int)pow(2,n)-1;
char*nums1,*nums2;
nums1=(char*)malloc(sizeof(char)*(n+1));
nums2=(char*)malloc(sizeof(char)*(n+1));
printf("---------开始穷举所有可能的组合----------
");
memset(c1.books,'0',n);
memset(c2.books,'1',n);
c1.books[n]=c2.books[n]=0;
printf("%s
",c1.books);
printf("%s
",c2.books);
if(checkOverLoad(c1,c2,bws,n)==0)
{
memset(nums1,0,n+1);
memset(nums2,0,n+1);
strcpy(nums1,c1.books);
strcpy(nums2,c2.books);
if(flag==1)
return0;
}
printf("
");
for(i=0;i<max;i++)
{
add2(c1.books);
sub2(c2.books);
printf("%s
",c1.books);
printf("%s
",c2.books);
if(checkOverLoad(c1,c2,bws,n)==0)
{
memset(nums1,0,n+1);
memset(nums2,0,n+1);
strcpy(nums1,c1.books);
strcpy(nums2,c2.books);
if(flag==1)
return0;
}
printf("
");
}
printf("-----------------穷举结束------------------
");
memset(c1.books,0,n+1);
memset(c2.books,0,n+1);
strcpy(c1.books,nums1);
strcpy(c2.books,nums2);
free(nums1);
free(nums2);
return0;
}
voidadd2(char*nums)//2进制字符串加1
{
inti,n=strlen(nums),jin=0;
for(i=n-1;i>=0;i--)
{
if(nums[i]=='0'&&i==n-1)
{
nums[i]='1';
break;
}
elseif(nums[i]-'0'+jin==1&&i<n-1)
{
nums[i]='1';
break;
}
else
{
jin=1;
nums[i]='0';
}
}
}
voidsub2(char*nums)//2进制字符串减1
{
inti,n=strlen(nums),j=0;
for(i=n-1;i>=0;i--)
{
if(nums[i]=='1'&&i==n-1)
{
nums[i]='0';
break;
}
elseif(nums[i]-'0'-j==0&&i!=n-1)
{
nums[i]='0';
break;
}
else
{
nums[i]='1';
j=1;
}
}
}
intcheckOverLoad(BAGc1,BAGc2,int*bws,intn)//检查是否超载。超载返回1,否返回0
{
inti,sum1=0,sum2=0;
for(i=0;i<n;i++)
if(c1.books[i]=='1')
sum1=sum1+bws[i];
else
sum2=sum2+bws[i];
if(sum1>c1.bweight)
{
printf("背包1超载!
");
return1;
}
if(sum2>c2.bweight)
{
printf("背包2超载!
");
return1;
}
printf("方案可行!
");
return0;
}
D. c语言中,总结穷举法适合求解的问题类型
穷举法用于数据乱序或者没有太好办法时,罗列出所有可行答案来筛选。典型的适用穷举法的编程初学问题有:百鸡问题、顺序查找、密码的暴力破解等。 穷举法的思路是,列举出所有可能的情况,逐个判断有哪些是符合问题所要求的条件,从而得到问题的解答。用于解决“是否存在”和“有多少可能性”等类型问题。 穷举法一般用循环或循环嵌套结构实现,要注意循环的起点和终点,对可能的情况不能遗漏,一般也不应重复。 1、穷举法的基本思路是把问题涉及的可能情况一一罗列出来,并且根据题目的条件和实际背景逐个作出判断,从中挑选出符合条件的解答。 2、使用穷举法时,要恰当地设计变量,并且决定用哪些变量作为搜索的主线,以便穷举出所有可能情况。 3、穷举一般使用循环结构,要注意循环的起点和终点,对可能的情况不能遗漏,一般也不应重复。 4、编制程序时,还应当根据题目要求准确地写出是否符合条件的判断语句。
E. c语言编程_穷举法求两个数的最大公约数
求最大公约数算法:
(1)辗转相除法
两整数a和b:
① a%b得余数c
② 若c=0,则b即为两数的最大公约数,结束
③ 若c≠0,则a=b,b=c,再回去执行①
(2)相减法
两整数a和b:
① 若a>b,则a=a-b
② 若a<b,则b=b-a
③ 若a=b,则a(或b)即为两数的最大公约数,结束
④ 若a≠b,则再回去执行①
(3)穷举法:
① i= a b中的小数
② 若a,b能同时被i整除,则i即为最大公约数,结束
③ i--,再回去执行②
相关代码:
#include <stdio.h>
int xc_gcd(int a,int b)
{
int c;
c=a%b;
while( c!=0 )
{
a=b;
b=c;
c=a%b;
}
return b;
}
int xj_gcd(int a,int b)
{
while( a!=b )
{
if ( a>b )
a-=b;
else
b-=a;
}
return b;
}
int qj_gcd(int a,int b)
{
int i;
i=(a>b)?a:b;
while( a%i!=0 && b%i!=0 )
i--;
return i;
}
void main()
{
//int a=36,b=27;
//int a=27,b=36;
int a=100,b=201;
printf("a=%d b=%d\n", a, b );
printf("辗转相除法求最大公约数=%d\n", xc_gcd(a,b) );
printf("相减法求最大公约数=%d\n", xc_gcd(a,b) );
printf("穷举法求最大公约数=%d\n", xc_gcd(a,b) );
}
F. c语言的穷举法
20个5分的是1元
50个2分的是1元
100个1分的是1元
上面定义的是这三种面值的银币不能超过的数量~
必须小于这些数量,要不然不就超过1元了,就不符合题意了~~
G. 什么是c语言里面的穷举法
假如有有一个账号登录需要六位数字密码,你可以编一个程序把所有可能的数字按顺序输入直到正确的那个为止。
如果有字母就把字母的可能性也加上。
如果密码太复杂,电脑在强大也需很长时间解决,穷举法用于简单的破解。
H. C语言穷举法
为啥它们范围会这样取,为啥x会从1-14,这是需要仔细推算的。因为本题的计算量很小,有时就图自己省力(少算一点)让计算机多算一点。
因为x至少是1,而y>x,z>y,为简单起见,而x、y、z的单价分别为a、b、c,所以,ax+by+cz=800
而ax+by+cz>ax+bx+cx
所以,800>(a+b+c)x
x<800/(30+20+10),即x<=13(取整数)
同样的道理,y最小是2,800=30+20y+10z>30+20y+10y,y最大=770/30=25
I. c 语言中“穷举”是啥意思
穷举 是列出所有的可能情况,对其一一判断
你说的是不是“枚举”
枚举是指规定某个变量只能取几个固定的值