常用简单算法与技巧c++版.docx

上传人:b****8 文档编号:23609568 上传时间:2023-05-19 格式:DOCX 页数:25 大小:29.74KB
下载 相关 举报
常用简单算法与技巧c++版.docx_第1页
第1页 / 共25页
常用简单算法与技巧c++版.docx_第2页
第2页 / 共25页
常用简单算法与技巧c++版.docx_第3页
第3页 / 共25页
常用简单算法与技巧c++版.docx_第4页
第4页 / 共25页
常用简单算法与技巧c++版.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

常用简单算法与技巧c++版.docx

《常用简单算法与技巧c++版.docx》由会员分享,可在线阅读,更多相关《常用简单算法与技巧c++版.docx(25页珍藏版)》请在冰豆网上搜索。

常用简单算法与技巧c++版.docx

常用简单算法与技巧c++版

简单算法列表:

1、两个数的值的交换

借用第三个变量来实现

cin>>a>>b;

c=a;a=b;b=c;

不借用第三个变量的方法

cin>>a>>b;

a=a+b;

b=a-b;

a=a-b;

2、小数位数的处理

#include//调用格式库

cout<

(2)<

3、数字的分离

输入一个四位数,将各个位上的数分离出来,当然如果用字符串来处理也行

cin>>a;

b=a%10;

c=a/10%10;

d=a/100%10;

e=a/1000;

如果是输入一个不知道位数的整数,要将其倒序输出

cin>>a;

b=0;

for(;a!

=0;)

{

 b=b*10+a%10;//将a数的个位取出来累加到b中

 a=a/10;//将a的个位去掉

}

cout<

4、判断一个数是否能被另一个数整除的方法

如判断一个数能否被7整除

cin>>a;

if(a%7==0)cout<<”yes”;

elsecout<<”no”;

如此推广到奇偶数的判断

cin>>a;

if(a%2==0)cout<<”偶数”;

elsecout<<”奇数”;

5、计数器

j=0;

j=j+1;

cin>>n;j=0;//计数器初值一般为0

for(i=1;i<=n;i++){

 cin>>a;

 if(a%2==0)j=j+1;//每次用自身加上1再赋给自身,即j++

}

cout<

6、累加器

s=0;//累加器的初值一般为0

cin>>a;

s=s+a;//将新数加上自身再赋给自身

cin>>n;s=0;

for(i=1;i<=n;i++){

 cin>>a;

 s=s+a;

}

cout<

7、累乘器

s=1;//累乘器的初值一般为1

cin>>a;

s=s*a;//将新数乘上自身在赋给自身

cin>>n;s=1;

for(i=1;i<=n;i++){

 cin>>a;

 s=s*a;

}

cout<

8、标记法(求素数)

输入整数n,请判断其是否为质数。

 cin>>n;

 f=1;  //用f做标记,为1则表示是素数

 for(j=2;j

   if(n%j==0)f=0; //f为0,则表示n在2~n-1之间有一个约数

 if(f==1)cout<<”yes”;

 elsecout<<”no”;

9、求最大值

先假设输入的第一个数即为最大数,然后用它去和后面的数一一进行比较,如果后面的数比它大,则将大的数交换给它。

cin>>a;

max=a;

for(i=1;i

 {cin>>a;if(a>max)max=a;}

10、求最小值

先假设输入的第一个数即为最小数,然后用它去和后面的数一一进行比较,如果后面的数比它小,则将小的数交换给它。

cin>>a;

min=a;

for(i=1;i

 {cin>>a;if(a

11、字符的处理

出入一串字母和数字,以”.“号结束,统计其中字母和数字的个数。

zimu=0;shuzi=0;

for(cin>>a;a!

=’.’;)

{

 if(a>=’a’&&a<=’z’||a>=’A’&&a<=’Z’)zimu++;

 if(a>=’0’&&a<=’9’)shuzi++;

 cin>>a;

}

输入一串小写字母,以”.“号结束,输出字母所对应的数字,规定a对应数字1,b对应数字2,z对应数字26,输出的数字间以空格隔开。

for(cin>>a;a!

=’.’;)

{

 if(a>=’a’&&a<=’z’)n=a-‘a’+1;

 cout<

 cin>>a;

}

//字母类型的数字要转为对应的整数可以采取同样的办法,

//intn;chara;cin>>a;n=a-‘0’;

空格的处理

cin命令做输入时会自动跳过空格和回车等符号,如果要求对空格进行处理则需要用到cin.get(a);也可以用scanf(“%c”,&a);但不能用cin>>a;

12、数学函数库

有一些标准数学函数在信息奥赛中是允许使用的,使用时要加上数学函数库

#include

doublea,b,c,d;

cin>>a>>b;

c=sqrt(a);//sqrt为求平方根函数

d=pow(a,b);//pow为求ab的函数,求平方可以用它,注意它的参数为实数类型

13、求最大公约数

求两自然数m,n的最大公约数。

最大公约数:

能同时被m和n整除的最大数。

如6和4的最大公约数为2

1)欧几里德算法(m>n)

①m被n除得到余数r(0≤r≤n)      r=m%n

②若r=0,则算法结束,n为最大公约数,否则做3

③m=n,n=r,回到1

使用的是循环迭代的方法

m=6  n=4   r=m%n=6%4=2

m=4  n=2   r=m%n=4%2=0

所以,公约数=2

程序代码:

 cin>>m>>n;

 for(r=m%n;r!

=0;r=m%n)

 {m=n;n=r;}

 cout<

2)穷举

最大公约数只能是n,n-1,...,2,1中的一个,一一列举出来试一下即可。

 cin>>m>>n;

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

   if(m%i==0&&n%i==0){cout<

虽然两种算法都可以求出最大公约数,但执行效率不同,穷举显然循环次数最多,最费时。

比如30002002这两个数,用穷举要执行2001次循环,而欧几里德算法只需要4次,算法的优劣一目了然。

14、求最小公倍数

最小公倍数:

能同时整除m和n的最小数。

1)已知最大公约数时的方法

最小公倍数为两数之积除以最大公约数。

接上例4和6的最小公倍数为4*6/2=12。

2)直接尝试

 cin>>m>>n;

 for(t=m;m%n!

=0;m=m+t);

 cout<

将较大数的值放在变量t中,每次用m直接加上t去尝试能否除尽n,如果能,现在的m就是最小公倍数。

大多时候还是应该选择使用第一种方法,仍以30002002为例,用第一种方法只需要4次循环求出最大公约数,然后求出最小公倍数,而第二种方法要执行上千次才能出结果。

15、穷举法

穷举法也称为“枚举法”,这种算法基本思想是依题目的部分条件,确定答案的大致范围;在此范围

内,对所有可能的情况一一列举,逐一验证,直到全部情况验证完毕,或者得到了需要的结果。

若某个情况经验证符合题目的全部条件,则它就是本题的一个答案;若全部情况经验证后,都不符合

题目的全部条件,则原题无解。

用穷举法解题的大致步骤如下:

1)分析题目,确定所要求的解是什么?

2)确定解的可能取值范围是什么?

3)穷举出所有可能的解

4)验证每一个可能的解

5)优化

例:

鸡兔同笼问题

一个笼子里有鸡和兔,现在只知道里面一共有a个头,b只脚,问鸡和兔各有多少只(要求鸡和兔至少1只)?

inti,j,a,b;

cin>>a>>b;

for(i=1;i

 for(j=1;j

   if(i+j==a&&i*2+j*4==b)cout<

16、递推的思想

迭代的方法

例:

斐波那契数列(从第三项起为前面两项之和)

11235813…

cin>>n;

a1=1;

a2=1;

for(i=3;i<=n;i++)

{

 a3=a1+a2;

 a1=a2;

 a2=a3;

}

cout<

猴子吃桃问题。

猴子摘了一堆桃,第一天吃了一半,还嫌不过瘾,又吃了一个;第二天又吃了剩下的一半零一个;以后每天如此。

到第N天,猴子一看只剩下一个了。

问最初有多少个桃子?

cin>>n;

s=1;

for(i=2;i<=n;i++)

 s=(s+1)*2;

cout<

17、文件的处理方法

#include

usingnamespacestd;

ifstreamfin(“输入文件名”);

ofstreamfout(“输出文件名”);

例:

陶陶摘苹果(文件名:

apple.cpp)【问题描述】

陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果。

苹果成熟的时候,陶陶就会跑去摘苹果。

陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试。

现在已知10个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的最大高度,请帮陶陶算一下她能够摘到的苹果的数目。

假设她碰到苹果,苹果就会掉下来。

【输入文件】输入文件apple.in包括两行数据。

第一行只包括一个100到120之间(包含100和120)的整数(以厘米为单位),表示陶陶把手伸直的时候能够达到的最大高度。

第二行包含10个100到200之间(包括100和200)的整数(以厘米为单位)分别表示10个苹果到地面的高度,两个相邻的整数之间用一个空格隔开。

【输出文件】输出文件apple.out包括一行,这一行只包含一个整数,表示陶陶能够摘到的苹果的数目。

【样例输入】

110

100200150140129134167198200111

【样例输出】

5

#include

usingnamespacestd;

ifstreamfin("apple.in");

ofstreamfout("apple.out");

intmain(){

   intrg,sg,i,j=0;

   fin>>rg;

   for(i=0;i<10;i++){

     fin>>sg;

     if(sg<=rg+30)j++;

   }

   fout<

}

多重循环讲解与练习

for(;;)

{

 语句组;

 for(;;)

 {

   语句组;

 }

 语句组;

1、图形字符类

例1、输出m行n列*号

cin>>m>>n;

for(i=0;i

{

 for(j=0;j

 {

   cout<<‘*’;

 }

 cout<

外循环i=0时,内循环j从0一直变化到n-1,即内循环中的语句{cout<<‘*’;}被执行了n次,语句cout<

当外循环的i值变化到m退出时,内循环中的语句{cout<<‘*’;}一共被执行了m×n次。

有时每列上的字符个数不同,如

例2、n=3时,输出如下图形

*

**

***

cin>>n;

for(i=0;i

{

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

 {

   cout<<‘*’;

 }

 cout<

有时每列上的字符个数不向上面图形一般每行以1递增,如

例3、n=3时,输出如下图形

*

***

*****

cin>>n;

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

{

 for(j=1;j<=2*i-1;j++)//每行上的字符以2递增,因此是2*i

 {

   cout<<‘*’;

 }

 cout<

}

如果是这样的金字塔形式

例4、n=3,输出

 *

 ***

*****

可以看作是先输出了一个倒三角形的空格,然后再输出上例中的图形

cin>>n;

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

{

 for(j=1;j<=n-i;j++)//每行上的空格数是n-1,n-2,...,1,0这样一个递减序列,而i每次递增1,要将一个递增序列改为递减序列,直接在前面加上-号

   cout<<'';

 for(j=1;j<=2*i-1;j++)//每行上的字符以2递增,因此是2*i

 {

   cout<<‘*’;

 }

 cout<

}

练习:

可以尝试打出如下图形:

如n=3,要求输出

 ***

 ***

***

 *

 ***

*****

 ***

 *

 *   *

 *** ***

**********

 *        *

 ***      ***

***************

     ***

      *

 a

 bbb

ccccc

 bbb

 a

2、逻辑推理题目

解逻辑判断与推理题这类题首先要把复杂的逻辑关系进行分析、抽象、化简,然后进行尝试排除,得到最后结果。

可以用计算机来验证推断的结果,复杂的还可以直接用逻辑表达式来表示各种关系条件,用计算机穷举各种可能情况,再根据条件采取累试排除或选择需要的组合。

【例1】四位同学不知是哪一位打碎了教室窗户的玻璃,老师问是哪一个同学打的。

A说:

“不是我”,B说:

“是C”,C说:

“是D”,D反驳说:

“他胡说!

”。

四个人当中只有一个人说假话,试判断哪一位打碎了教室窗户的玻璃?

分析:

用A,B,C,D分别表示这四位同学,用1表示打碎了玻璃,0表示没有打碎。

题目中四句话可表示成:

A!

=1

C==1

D==1

D!

=1

A,B,C,D只有一位同学打碎了玻璃,因此A+B+C+D的值为1。

逻辑表达式只有1和0两个值,为1表示真,为0表示假,

只有一个人说假话,则说明四个表达式的和应为3。

程序如下:

for(A=0;A<2;A++)

for(B=0;B<2;B++)

for(C=0;C<2;C++)

for(D=0;D<2;D++)if(A+B+C+D==1&&(A!

=1)+(C==1)+(D==1)+(D!

=1)==3)

{if(A==1)cout<<'A';

if(B==1)cout<<'B';

if(C==1)cout<<'C';

if(D==1)cout<<'D';

}

四个循环分别用于穷举A,B,C,D四位同学打碎玻璃和没有打碎玻璃的所有情况,加上判断就可以确定到底是谁打碎了玻璃。

也可以用其他方法来做,尝试一下。

【例2】有四个学生对我国四大淡水湖排列次序如下:

甲:

洞庭湖最大,洪泽湖最小,鄱阳湖第三。

乙:

洞庭湖最小,洪泽湖最大,鄱阳湖第二,太湖第三。

丙:

洞庭湖第三,洪泽湖最小。

丁:

洪泽湖第二,鄱阳湖最大,太湖最小。

每人都只说对了一个,试编程排出正确次序。

分析:

用d、h、p、t分别表示洞庭湖、洪泽湖、鄱阳湖、太湖。

四个湖泊的顺序号只能是1、2、3、4的不同组合,所以d+h+p+t=10。

则四个人的话可表示为:

甲:

d==1,h==4,p==3

乙:

h==1,d==4,p==2,t==3

丙:

h==4,d==3

丁:

p==1,t==4,h==2,t==3

由于每人都只说对了一个,所以上述表示每个人的观点的式子中只有一个真值为1,其他为0。

程序如下:

for(d=1;d<5;d++)

for(h=1;h<5;h++)

for(p=1;p<5;p++)

for(t=1;t<5;t++)

if((d!

=h)&&(d!

=p)&&(d!

=t)&&

(h!

=p)&&(h!

=t)&&(p!

=t)&&

(d==1)+(h==4)+(p==3)==1&&

(d==4)+(h==1)+(p==2)+(t==3)==1&&

(d==3)+(h==4)==1&&

(h==2)+(p==1)+(t==4)==1)

{cout<<"dongtinghuis:

"<

cout<<"hongzehuis:

"<

cout<<"poyanghuis:

"<

cout<<"taihuis:

"<

}

程序写得稍嫌复杂,实际上可以简便一些。

for(d=1;d<5;d++)

for(h=1;h<5;h++)

if(d!

=h)

for(p=1;p<5;p++)

if(p!

=h&&p!

=d)

{t=10-d-h-p;

if((d==1)+(h==4)+(p==3)==1)

if((d==4)+(h==1)+(p==2)+(t==3)==1)

if((d==3)+(h==4)==1)

if((h==2)+(p==1)+(t==4)==1)

{cout<<"dongtinghuis:

"<

cout<<"hongzehuis:

"<

cout<<"poyanghuis:

"<

cout<<"taihuis:

"<

}

}

循环减少一个,表达式分开写,看起来要清晰些。

练习:

(1)某年级数学竞赛中,A、B、C、D、E五位同学获得前五名。

A说:

“D是第一,C是第四”;B说:

“A是第一,E是第二”;C说:

“B是第二,D是第三”;D说:

“E是第三,A是第五”;E说:

“E是第二,C是第四”。

每人都只说对了一个,试编程排出正确次序。

(2)甲、乙、丙三位同学中有一人趁大家不在教室的时候把教室打扫干净了。

事后老师问是谁做的好事。

甲说:

“是乙做的”,乙说:

“不是我”,丙说:

“不是我”。

三个人当中只有一个人说真话,试判断哪一位做了好事?

(3)有红、黄、蓝、白四色球各一个,放置在编号为1、2、3、4四个格子的盒中,每个格子中只能放一个小球,他们的顺序不知。

甲、乙、丙三人猜测的顺序如下:

甲说:

蓝色球编号为1,黄色球编号为2;乙说:

蓝色球编号为2,白色球编号为3;丙说:

红色球编号为2,白色球编号为4。

结果证明三个人各猜中一半。

问四个格子的盒中放置小球情况。

一维数组讲解与练习

一、为什么要使用数组

学到现在,我们用分支结构解决了计算机的智能判断问题,用循环充分利用了计算机处理速度快的特点,也可以用循环对大量数据进行处理,但这些数据却无法大量保存,在这点上还没有利用上计算机存储容量大的特点。

在程序语言中有一种数据结构可以解决这个问题,那就是数组。

  例1、输入1000个学生的某门课程的成绩,打印出低于平均分的同学号数与成绩。

分析:

在解决这个问题时,虽然可以通过读入一个数就累加一个数的办法来求学生的总分,进而求出平均分。

但因为只有读入最后一个学生的分数以后才能求得平均分,且要打印出低于平均分的同学,故必须把1000个学生的成绩都保留下来,然后逐个和平均分比较,把高于平均分的成绩打印出来。

如果,用简单变量a1,a2,…,a1000存放这些数据,可想而知程序要很长且繁。

要想如数学中使用下标变量ai形式表示这1000个数,则可以引入下标变量a[i]。

这样问题的程序可写为:

tot=0;//tot表示总分

for(i=1;i<=1000;i++)//环读入每一个学生的成绩,并累加它到总分}

{

  cin>>a[i];

  tot:

=tot+a[i];

}

ave=tot/1000;//计算平均分

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

 if(a[i]

'<

而要在程序中使用下标变量,则必须先说明这些下标变量的整体——数组,即数组是若干个同名(如上面的下标变量的名字都为a)下标变量的集合。

二、一维数组

1、一维数组的定义和引用

当数组中每个元素只带有一个下标时,我们称这样的数组为一维数组。

数组是同一类型的一组值(10个char、15个int…),在内存中顺序存放。

整个数组共用一个名字,而其中的每一项又称为一个元素。

1)定义方式:

类型说明符    数组名[常量表达式];

int a[4];   //int是数组元素的类型说明,4表示元素个数,a表示数组名称,整个说明表明a数组由4个int型元素组成,这四个元素分别是:

a[0],a[1],a[2],a[3]

要注意的两个地方:

其序号从0开始,而不是从1开始。

所以inta[4];实际上不包含a[4]这个元素

C++不允许对数组的大小作动态的定义,即数组的大小不能是变量,必须是常量。

即不能定义为inta[n];只能是inta[1000];等,即元素个数必须是确定的。

2)一维数组元素的引用

数组必须先定义,具体引用时(赋值、运算、输出)其元素等同于变量。

数组元素的赋值与输出通常采用的是循环。

例2、输入100个数,将其倒序输出。

intmain()

{  int i, a[100];

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

       cin>>a[i];

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

       cout<

}

3)一维数组的初始化

除了用循环读入处理外,一维数组还可以直接进行赋值操作。

inta,b=0,c[5]={1,2,3,4,5};

此例也可以写成,intc[5];c[0]=1;c[1]=2;c[2]=3;c[3]=4;c[4]=5;

注意:

不能给数组整体赋值,只能一个一个地赋值

比如上例写成:

inta,b=0,c[5]={1,2,…,5};就是错误的。

2、一位数组的应用实例

例3、求Fibonacci数列:

1,1,2,3,5,8,......的前20个数,将它们5个数一行的输出,每两个数之间隔一个制表符的距离。

分析:

Fibonacci数列可表示为以下数学递推公式:

 F1=1  (n=1)

 F2=1  (n=2)

 Fn=Fn-1+Fn-2 (n>=3)

intmain()

{  int i;

   int f[21];

f[1]=1;

f[2]=1;

   for(i=2;i<21;i++)

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

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

 {  

    cout<

if(i%5==0) cout<<“\n”;

 }

}

例4、输入十个正整数,把这十个数按由大到小的顺序排列。

将数据按一定顺序排列称为排序,排序的算法有很多,其中选择排序是一种较简单的方法。

分析:

要把十个数按从大到小顺序排列,则排完后,第一个数最大,第二个数次大,……。

因此,我们第一步可将第

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

当前位置:首页 > 工作范文 > 行政公文

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

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