九种基本算法概论.docx

上传人:b****8 文档编号:29832600 上传时间:2023-07-27 格式:DOCX 页数:23 大小:19.88KB
下载 相关 举报
九种基本算法概论.docx_第1页
第1页 / 共23页
九种基本算法概论.docx_第2页
第2页 / 共23页
九种基本算法概论.docx_第3页
第3页 / 共23页
九种基本算法概论.docx_第4页
第4页 / 共23页
九种基本算法概论.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

九种基本算法概论.docx

《九种基本算法概论.docx》由会员分享,可在线阅读,更多相关《九种基本算法概论.docx(23页珍藏版)》请在冰豆网上搜索。

九种基本算法概论.docx

九种基本算法概论

九种基本算法思想

一、枚举算法

1、基本思想

枚举法也叫穷举算法,是指将问题的所有可能的结果一一列举,然后根据条件判断是否适合,适合就保留,不是喝酒舍弃;一般采用while循环实现。

2、实例演练

百钱买百鸡问题:

公鸡每只5元,母鸡每只3元,小鸡3元一只。

先用100元钱,买公鸡、母鸡、小鸡各几只?

代码:

#include

intmain()

{

intx,y,z;

for(x=0;x<=20;x++)

{

for(y=0;y<=33;y++)

{

z=100-x-y;

if(z%3==0&&x*5+y*3+z/3==100)

printf("公鸡:

%d,母鸡:

%d,小鸡:

%d\n",x,y,z);

}

}

getch();

return0;

}

二、递推算法

1、算法思想:

具体分两种:

(1)顺推法:

从已知条件入手,逐步推算出要解决问题的方法。

例如斐波那契数列;

(2)逆推法:

从已知的结果出发,利用迭代表达式逐步推算出问题开始的条件;

2.实例演练:

(1)斐波那契数列(兔子的繁殖):

代码:

#include

#defineNUM13

intmain()

{

inti;

longfib[NUM]={1,1};

for(i=2;i

{

fib[i]=fib[i-1]+fib[i-2];

}

for(i=0;i

{

printf("%d月兔子总数:

%d\n",i,fib[i]);

}

getch();

return0;

}

(2)母亲为儿子大学四年生活费存了一笔钱,方式是整存零取,规定儿子每月月底取走下月的生活费1000元。

现在假设银行的年利率是1.71%,现在计算母亲至少存多少钱?

代码:

#include

#defineFETCH1000

#defineRATE0.0171

intmain()

{

doublecorpus[49];

inti;

corpus[48]=(double)FETCH;

for(i=47;i>0;i--)

{

corpus[i]=(corpus[i+1]+FETCH)/(1+RATE/12);

}

for(i=48;i>0;i--)

{

printf("第%d月末本利合计:

%.2f\n",i,corpus[i]);

}

getch();

return0;

}

三、递归算法

1.算法思想:

就是函数自己调用自己的算法;

2.实例演练:

(1)汉诺塔问题:

代码:

move(intn,intx,inty,intz)

{

if(n==1)

printf("%c-->%c\n",x,z);

else

{

move(n-1,x,z,y);

printf("%c-->%c\n",x,z);

{getchar();}

move(n-1,y,x,z);

}

}

main()

{

inth;

printf("inputnumber:

");

scanf("%d",&h);

printf("thesteptomoving%2ddiskes:

\n",h);

move(h,'a','b','c');

system("pause");

}

(2)阶乘问题:

代码:

#include

intfact(intn);

intmain()

{

inti;

printf("请输入要求阶乘的一个整数:

");

scanf("%d",&i);

printf("%d的阶乘结果为:

%d\n",i,fact(i));

getch();

return0;

}

intfact(intn)

{

if(n<=1)

return1;

else

returnn*fact(n-1);

}

四、分治算法

1.算法思想:

将一个规模为N的问题分解为K个规模较小的问题,这些问题相互独立且与原问题性质相同,我们只需要求出每个子问题的结果就可以得到原问题的结果。

2.实例演练:

大数相乘问题:

#include

#include

#include

#include

char*result='\0';

intpr=1;

voidgetFill(char*a,char*b,intia,intja,intib,intjb,inttbool,intmove){

intr,m,n,s,j,t;

char*stack;

m=a[ia]-48;

if(tbool){//直接从结果数组的标志位填入,这里用了堆栈思想

r=(jb-ib>ja-ia)?

(jb-ib):

(ja-ia);

stack=(char*)malloc(r+4);

for(r=j=0,s=jb;s>=ib;r++,s--){

n=b[s]-48;

stack[r]=(m*n+j)%10;

j=(m*n+j)/10;

}

if(j){

stack[r]=j;

r++;

}

for(r--;r>=0;r--,pr++)

result[pr]=stack[r];

free(stack);

for(move=move+pr;pr

result[pr]='\0';

}

else{//与结果的某几位相加,这里不改变标志位pr的值

r=pr-move-1;

for(s=jb,j=0;s>=ib;r--,s--){

n=b[s]-48;

t=m*n+j+result[r];

result[r]=t%10;

j=t/10;

}

for(;j;r--){

t=j+result[r];

result[r]=t%10;

j=t/10;

}

}

}

intget(char*a,char*b,intia,intja,intib,intjb,intt,intmove){

intm,n,s,j;

if(ia==ja){

getFill(a,b,ia,ja,ib,jb,t,move);

return1;

}

elseif(ib==jb){

getFill(b,a,ib,jb,ia,ja,t,move);

return1;

}

else{

m=(ja+ia)/2;

n=(jb+ib)/2;

s=ja-m;

j=jb-n;

get(a,b,ia,m,ib,n,t,s+j+move);

get(a,b,ia,m,n+1,jb,0,s+move);

get(a,b,m+1,ja,ib,n,0,j+move);

get(a,b,m+1,ja,n+1,jb,0,0+move);

}

return0;

}

intmain(){

char*a,*b;

intn,flag;

a=(char*)malloc(1000);

b=(char*)malloc(1000);

printf("Theprogramwillcomputera*b\n");

printf("Enterab:

");

scanf("%s%s",a,b);

result=(char*)malloc(strlen(a)+strlen(b)+2);

flag=pr=1;

result[0]='\0';

if(a[0]=='-'&&b[0]=='-')

get(a,b,1,strlen(a)-1,1,strlen(b)-1,1,0);

if(a[0]=='-'&&b[0]!

='-'){

flag=0;

get(a,b,1,strlen(a)-1,0,strlen(b)-1,1,0);

}

if(a[0]!

='-'&&b[0]=='-'){

flag=0;

get(a,b,0,strlen(a)-1,1,strlen(b)-1,1,0);

}

if(a[0]!

='-'&&b[0]!

='-')

get(a,b,0,strlen(a)-1,0,strlen(b)-1,1,0);

if(!

flag)

printf("-");

if(result[0])

printf("%d",result[0]);

for(n=1;n

printf("%d",result[n]);

printf("\n");

free(a);

free(b);

free(result);

system("pause");

return0;

}

五、贪心算法

1.算法思想:

也叫贪婪法。

在求解问题时总是做出在当下看来是最好的抉择的方法。

2.实例演练

(1)人民币找零问题:

#include

#defineMAXN9

intparvalue[MAXN]={10000,5000,2000,1000,500,100,50,10};

intnum[MAXN]={0};

intexchange(intn)

{

inti,j;

for(i=0;i

if(n>parvalue[i])break;//找到比n小的最大面额

while(n>0&&i

{

if(n>=parvalue[i])

{

n-=parvalue[i];

num[i]++;

}elseif(n<10&&n>=5)

{

num[MAXN-1]++;

break;

}elsei++;

}

return0;

}

intmain()

{

inti;

floatm;

printf("请输入找零的金额:

");

scanf("%f",&m);

exchange((int)100*m);

printf("\n%.2f元零钱的组成:

\n",m);

for(i=0;i

if(num[i]>0)

printf("%6.2f:

%d张\n",(float)parvalue[i]/100.0,num[i]);

getch();

return0;

}

(3)装箱问题:

#include

#include

#defineN6

#defineV100

typedefstructbox

{

intno;

intsize;

structbox*next;

}BOX;

voidinit_list(BOX**H)

{

*H=(BOX*)malloc(sizeof(BOX));

(*H)->no=0;

(*H)->size=0;

(*H)->next=NULL;

}

BOX*find_p(BOX*H,intvolume,intv)

{

BOX*p=H->next;

while(p!

=NULL)

{

if(p->size+volume<=v)

break;

p=p->next;

}

returnp;

}

voidadd_list_tail(BOX*H,BOX*p)

{

BOX*tmp=H->next;

BOX*q=H;

while(tmp!

=NULL)

{

q=tmp;

tmp=tmp->next;

}

q->next=p;

}

voidprint_list(BOX*H)

{

BOX*p=H->next;

while(p!

=NULL)

{

printf("%d:

%d\n",p->no,p->size);

p=p->next;

}

}

intadd_box(intvolume[],intv)

{

intcount=0;

inti;

BOX*H=NULL;

init_list(&H);

for(i=0;i

{

BOX*p=find_p(H,volume[i],v);

if(p==NULL)

{

count++;

p=(BOX*)malloc(sizeof(BOX));

p->no=count;

p->size=volume[i];

p->next=NULL;

add_list_tail(H,p);

}

else

{

p->size+=volume[i];

}

}

print_list(H);

returncount;

}

intmain(intargc,char*argv[])

{

intret;

intvolumes[]={60,45,35,20,20,20};

ret=add_box(volumes,V);

printf("%d\n",ret);

system("PAUSE");

return0;

}

六、动态规划

1.算法思想:

是系统分析算法的一种常用算法,根据时空的特点,将复杂问题分成若干的小阶段,在选定系统上进行方向之后,逆向从终点开始计算,逐次对每个阶段寻找某种策略,使得整个过程达到最优。

通常分成两个阶段:

划分阶段;选择状态。

2.实例演练:

求两个字符串的最长公共子串:

#include

#include

#defineMAXLEN100

voidLCSLength(char*x,char*y,intm,intn,intc[][MAXLEN],intb[][MAXLEN])

{

inti,j;

for(i=0;i<=m;i++)

c[i][0]=0;

for(j=1;j<=n;j++)

c[0][j]=0;

for(i=1;i<=m;i++)

{

for(j=1;j<=n;j++)

{

if(x[i-1]==y[j-1])

{

c[i][j]=c[i-1][j-1]+1;

b[i][j]=0;

}

elseif(c[i-1][j]>=c[i][j-1])

{

c[i][j]=c[i-1][j];

b[i][j]=1;

}

else

{

c[i][j]=c[i][j-1];

b[i][j]=-1;

}

}

}

}

voidPrintLCS(intb[][MAXLEN],char*x,inti,intj)

{

if(i==0||j==0)

return;

if(b[i][j]==0)

{

PrintLCS(b,x,i-1,j-1);

printf("%c",x[i-1]);

}

elseif(b[i][j]==1)

PrintLCS(b,x,i-1,j);

else

PrintLCS(b,x,i,j-1);

}

intmain(intargc,char**argv)

{

charx[MAXLEN]={"ABCBDAB"};

chary[MAXLEN]={"BDCABA"};

intb[MAXLEN][MAXLEN];

intc[MAXLEN][MAXLEN];

intm,n;

m=strlen(x);

n=strlen(y);

LCSLength(x,y,m,n,c,b);

PrintLCS(b,x,m,n);

getch();

return0;

}

七、试探算法

1.算法思想

又称回溯法,先暂且放弃关于问题规模大小的限制,并将问题的候选解按照某种次序逐一枚举和检验,当发现当前候选解不可能是正确解时就选择下一个候选解,若是,则扩大当前候选解的规模。

2.实例演练:

八皇后问题:

#include

#defineN8

intsolution[N],j,k,count,sols;

intplace(introw,intcol)

{

for(j=0;j

{

if(row-j==solution[row]-solution[j]||row+solution[row]==j+solution[j]||solution[j]==solution[row])

return0;

}

return1;

}

voidbacktrack(introw)

{

count++;

if(N==row)

{

sols++;

for(k=0;k

printf("%d\t",solution[k]);

printf("\n\n");

}

else

{

inti;

for(i=0;i

{

solution[row]=i;

if(place(row,i))

backtrack(row+1);

}

}

}

voidqueens()

{

backtrack(0);

}

intmain(void)

{

queens();

printf("TotalSolutions:

%d\n",sols);

getch();

return0;

}

八、迭代算法

1.算法思想:

也成辗转法。

不断用变量的旧值递推新值的算法;

2.实例演练:

求平方根:

#include

#include

voidmain()

{

doublea,x0,x1;

printf("Inputa:

\n");

scanf("%lf",&a);//为什么在VC6.0中不能写成“scanf("%f",&a);”?

if(a<0)

printf("Error!

\n");

else

{

x0=a/2;

x1=(x0+a/x0)/2;

do

{

x0=x1;

x1=(x0+a/x0)/2;

}while(fabs(x0-x1)>=1e-6);

}

printf("Result:

\n");

printf("sqrt(%g)=%g\n",a,x1);

getch();

return0;

}

九、模拟算法

1.算法思想:

模拟算法是最基本的算法,是根据题目的规则对题目进行编程模拟。

例如在C语言中使用srand()初始化随机数发生器,然后利用rand()函数来生成随机数。

2.实例演练:

(1)猜数游戏:

#include

#include

intmain()

{

intn,m,i=0;

srand(time(NULL));

n=rand()%100+1;

do{

printf("输入所猜数字:

");

scanf("%d",&m);

i++;

if(m>n)

printf("错误!

所猜数太大了!

\n");

elseif(m

printf("错误!

所猜数太小了!

\n");

}while(m!

=n);

printf("答对了!

\n");

printf("共猜测了%d次。

\n",i);

if(i<=5)

printf("你太聪明了,这么快就猜出来了!

");

elseif(i>5)

printf("还需改进方法,以便更快猜出来!

");

getch();

return0;

}

(2)掷骰子游戏:

#include

#include

voidplay(intn)

{

inti,m=0,t=0;

for(i=0;i

{

t=rand()%6+1;

m+=t;

printf("\t第%d粒:

%d;\n",i+1,t);

}

printf("\t总点数为:

%d\n",m);

}

intmain(void)

{

intc;//参赛人数

intn;//骰子数量

inti,m;

do{

srand(time(NULL));

printf("设置骰子数量(输入0退出):

");

scanf("%d",&n);

if(n==0)break;//至少一个骰子

printf("\n输入本轮参赛人数(输入0退出):

");

scanf("%d",&c);

if(c==0)break;

for(i=0;i

{

printf("\n第%d位选手掷出的骰子为:

\n",i+1);

play(n);

}

printf("\n");

}while

(1);

return0;

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 动态背景

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1