常用简单算法与技巧c++版.docx
- 文档编号:23609568
- 上传时间:2023-05-19
- 格式:DOCX
- 页数:25
- 大小:29.74KB
常用简单算法与技巧c++版.docx
《常用简单算法与技巧c++版.docx》由会员分享,可在线阅读,更多相关《常用简单算法与技巧c++版.docx(25页珍藏版)》请在冰豆网上搜索。
常用简单算法与技巧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++)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 常用 简单 算法 技巧 c+