开始系统学习算法,希望自己能够坚持下去,期间会把常用到的算法写进此博客,便于以后复习,同时希望能够给初学者提供一定的帮助,手敲难免存在错误,欢迎评论指正,共同学习。博客也可能会引用别人写的代码,如有引用,定会注明。本博客内容主要按照算法笔记内容进行学习。(2018-12-03)
1.万能头文件
#include<bits/stdc++.h> using namespace std;
int main(){
...
return 0;
}
2.判断素数
int IsPrime(int n){ for(int i=2;i<=sqrt(n+1);i++){ if(n%i==0){ return 0; } } return 1; } //返回0代表不是素数,返回1代表是素数
3.求一元二次方程的根
题目链接(点击进入)
数学内容:
输出格式:
补充:%0md(m代表宽度,右对齐),当变量不足m位时,将在前面补0,例如a=123,%05d,则输出结果为00123
#include<stdio.h> #include<math.h> int main(){ double a,b,c; double r1,r2; scanf("%lf%lf%lf",&a,&b,&c); r1 = (-1*b+sqrt(b*b-4*a*c))/(2*a); r2 = (-1*b-sqrt(b*b-4*a*c))/(2*a); printf("r1=%7.2lf r2=%7.2lf",r1,r2); return 0; }
4.特殊符号输出
想要输出%或,则需要在前面再加一个%或
#include<stdio.h> int main(){ printf("%% "); printf("\"); return 0; }
5.getchar与putchar的使用
getchar用来接收输入的单个字符,putchar用来输出单个字符
#include<stdio.h> int main(){ char a,b,c; a = getchar(); getchar(); b = getchar(); c = getchar(); putchar(a); putchar(b); putchar(c); return 0; } /*输入数据:abcd 输出数据:abd 原因:字符b虽然被接收,但是没有用变量进行保存,所以丢失 ps:getchar可以接收Enter键的内容,以 的形式保存 */
6.常用math函数(使用需加头文件#include<math.h>)
1)fabs(double x)
该函数用于对double型变量取绝对值
#include<stdio.h> #include<math.h> int main(){ double db =-12.56; printf("%.2f ",fabs(db)); return 0; } //输出结果:12.56
2)floor(double x)和ceil(double x)
这两个函数分别用于double型变量的向下取整和向上取整,返回类型为double型
#include<stdio.h> #include<math.h> int main(){ double db1 = -5.2, db2 = 5.2; printf("%.0f %.0f ",floor(db1),ceil(db1)); printf("%.0f %.0f ",floor(db2),ceil(db2)); return 0; } /*输出结果: -6 -5 5 6*/
3)pow(double r,double p)
该函数用于返回rp,要求r和p都是double型
#include<stdio.h> #include<math.h> int main(){ double db = pow(2.0,3.0); printf("%f ",db); return 0; /*int型也可以使用 int a=2,b=3; int db2 = pow(a,b); print("%d ",db2) */ } /*输出结果: 8.000000 */
4)sqrt(double x)
该函数用于返回double型变量的算术平方根
#include<stdio.h> #include<math.h> int main(){ double db = sqrt(2.0); printf("%f ",db); return 0; } /*输出结果: 1.414214 */
5)log(double x)
该函数用于返回double型变量的以自然对数为底的对数
ps:C语言中没有对任意底数求对数的函数,因此必须使用换底公式来将不是以自然对数为底的对数转换为以e为底的对数,即logab=logeb / logea。
#include<stdio.h> #include<math.h> int main(){ double db = log(1.0); printf("%f ",db); return 0; } /*输出结果: 0.000000 */
6)round(double x)
该函式用于将double型变量x四舍五入,返回类型也是double型,需进行取整
#include<stdio.h> #include<math.h> int main(){ double db1 = round(3.40); double db2 = round(3.45); double db3 = round(3.50); double db4 = round(3.55); double db5 = round(3.60); printf("%d, %d, %d, %d, %d ",(int)db1,(int)db2,(int)db3,(int)db4,(int)db5); return 0; } //输出结果:3,3,4,4,4
7.switch语句的用法
格式:
switch(表达式){ case 常量表达式1: ... break; case 常量表达式2: ... break; ... case 常量表达式n: ... break; default: ... }
实例:
#include<stdio.h> int main(){ int a = 1, b = 2; switch(a + b){ case 1: printf("%d ",a); break; case 2: printf("%d ",b); break; case 3: printf("%d ",a + b); break; default: printf("None "); } return 0; } //输出结果:3
8.求圆周率π的近似值
题目链接:圆周率近似值(点击此处)
由于题目没有给出解法,也没有相关提示,所以我就参考了一下别人的解法,这里的核心就是求圆周率近似值的公式:
针对本题的代码:
#include<stdio.h> #include<math.h> int main(){//解法:用π/4 ≈ 1 - 1/3 + 1/5 - 1/7 +... 公式 int n=1; double ans;//结果 double tmp = 1.0;//分子 while(n<=pow(10,6)){//题中要求为某一项绝对值小于10的-6次方,即1/n里的n要大于10的六6次方 ans += tmp/n*1.0; n = n + 2; tmp = tmp*-1.0; } ans = ans * 4; printf("PI=%10.8f ",ans); }
9.Fibonacci数列
题目链接:http://www.codeup.cn/problem.php?cid=100000568&pid=7
1)递归法求解
#include<stdio.h> #include<math.h> int Fib(int n){ if(n==1||n==2){ return 1; }else{ return Fib(n-1)+Fib(n-2); } } int main(){ int n; scanf("%d",&n); printf("%d",Fib(n)); return 0; }
2)概念法求解
#include<stdio.h> #include<math.h> int Fib(int n){ int i; int f1 = 1; int f2 = 1; int f3 = 1;//避免判断n是否大于2 for(i = 2;i<n;i++) { f3 = f1 + f2; f1 = f2; f2 = f3; } return f3; } int main(){ int n; scanf("%d",&n); printf("%d",Fib(n)); return 0; }
【转】参考博客地址:https://blog.csdn.net/weixin_40740059/article/details/80012909
10.分数序列求和
题目描述:有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13…求出这个数列的前 20 项之和。
#include<stdio.h> int main(){ double n1=2.0,m1=1.0; double n2=3.0,m2=2.0; double n3,m3; double ans=(n1/m1)+(n2/m2); for(int i=3;i<=20;i++){ n3 = n1 + n2; m3 = m1 + m2; ans+=(n3/m3); n1 = n2; m1 = m2; n2 = n3; m2 = m3; } printf("%.6f ",ans); return 0; }
11.冒泡排序
冒泡排序是排序中最基本的一种方法,虽然在写题时我们一般不会去使用它,但我觉得了解冒泡排序算法的实现原理确实非常必要的。
冒泡排序的本质在于交换,即每次通过交换的方式把当前剩余元素的最大值移动到一端,当剩余元素为0时,排序结束。
这里附上一个辅助学习数据结构的网站:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html(模拟常见数据结构的运行过程)
#include<stdio.h> int main(){ int a[10]={3,1,4,5,2}; for(int i=1;i<=4;i++){//进行n-1趟比较 for(int j=0;j<5-i;j++){//将剩余的数进行交换,选出最大的那一个 if(a[j]>a[j+1]){//交换 int temp = a[j]; a[j] = a[j+1]; a[j+1] = temp; } } } for(int i=0;i<5;i++){ printf("%d ",a[i]); } return 0; }
//输出结果:1 2 3 4 5
题目链接:http://www.codeup.cn/problem.php?cid=100000569&pid=7
12.二维数组的初始化
#include<stdio.h> int main(){ int a[5][6]={{3,1,2},{8,4},{},{1,2,3,4,5}}; for(int i=0;i<5;i++){ for(int j=0;j<6;j++){ printf("%d ",a[i][j]); } printf(" "); } return 0; } /*输出结果: 3 1 2 0 0 0 8 4 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 0 0 0 0 0 0 0 */
特别提醒:如果数组大小较大(大概是106),则需要将其定义在主函数外,否则会使程序异常退出,原因是函数内部申请的局部变量来自系统栈,允许申请的空间较小;而函数外部申请的全局变量
来自静态存储区,允许申请的空间较大。
13.memset函数的使用
memset函数的功能是给数组中的每一个元素都赋予相同的值
使用格式:memset(数组名,值,sizeof(数组名))
注意:使用需加头文件 #include<string.h>,另外只建议使用memset赋0或-1
#include<stdio.h> #include<string.h> int main(){ int a[5]={1,2,3,4,5}; memset(a,0,sizeof(a)); for(int i=0;i<5;i++){ printf("%d ",a[i]); } printf(" "); memset(a,-1,sizeof(a)); for(int i=0;i<5;i++){ printf("%d ",a[i]); } printf(" "); return 0; } /*输出结果: 0 0 0 0 0 0 -1 -1 -1 -1 -1 */
14.字符数组初始化
#include<stdio.h> #include<string.h> int main(){ char str[15] = {'G','O','O','D',' ','B','O','Y','!'}; for(int i=0;i<9;i++){ printf("%c",str[i]); } printf(" "); return 0; } /*输出结果: GOOD BOY! */
除此之外,字符数组也可以通过赋值字符串来初始化(仅限于初始化,程序其它位置不允许这样直接赋值整个字符串)
#include<stdio.h> #include<string.h> int main(){ char str[15] = "GOOD BOY!"; for(int i=0;i<9;i++){ printf("%c",str[i]); } printf(" "); return 0; } /*输出结果: GOOD BOY! */
15.字符数组的输入输出
1)scanf输入,printf输出
scanf对字符类型有%c和%s两种格式(printf同理),其中%c用来输入输出单个字符,%s用来输入一个字符串并存在数组里或输出一个字符串。
%c能识别空格和换行,%s将空格和换行识别一个字符串的结束。
#include<stdio.h> int main(){ char str[10]; scanf("%s",str); printf("%s ",str); return 0; } /* 输入: ATA QAQ 输出结果: ATA */
scanf输入%s不需要加&。
2)getchar输入,putchar输出
getchar和putchar分别用来输入输出单个字符
#include<stdio.h> int main(){ char str[5][5]; for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ str[i][j]=getchar(); } getchar();//用来吸收每行结束输入的换行符(enter键) } for(int i = 0;i<3;i++){ for(int j=0;j<3;j++){ putchar(str[i][j]); } putchar(' '); } return 0; } /* 输入: ATA QAQ ATA 输出结果: ATA QAQ ATA */
3)gets输入,puts输出
gets用来输入一行字符串(注意:gets识别换行符 作为输入结束,因此scanf完一个整数后,如果使用gets,需先用getchar接收输入整数后的换行符),并将其存放于一维数组中;
puts用来输出一行字符串,并紧跟一个换行
#include<stdio.h> int main(){ char str1[20]; char str2[5][10]; gets(str1); for(int i=0;i<3;i++){ gets(str2[i]); } puts(str1); for(int i=0;i<3;i++){ puts(str2[i]); } return 0; } /* 输入: abcdefghi QAQ ATA ATA 输出结果: abcdefghi QAQ ATA ATA */
特别提醒:gets和scanf的输入方式会默认在每个字符串的后面添加一个空字符' ',然后puts和printf就是通过识别' '作为字符串的结尾输出的。
所以如果不是使用scanf的%s格式或者gets函数输入字符串,一定要在字符串的结尾加上' ',否则使用printf和puts进行输出时会出错。
#include<stdio.h> int main(){ char str[20]={'a','b','