算法竞赛入门(1)学习笔记——程序设计入门


概要: 本节所讲内容包括:浮点数、整数;输入与输出;数学库的应用(pi的计算,sqrt函数,三角函数);数字反转(包括0反转在首位的问题);数字的交换(三变量法、两变量法和黑盒思路);分支结构;三个数字比较大小(常规六条分支和交换法)。

一:算术表达式

1.1整数和浮点数
输出函数中,通过“”里面的来限制整数和浮点数。
“%d\n”表示输出的是整数
"%d.10f\n"表示输出的是浮点数,并且.f就是小数点后几位。最高可以
整数算式就用整数,浮点数就用浮点数算式。

#include<stdio.h>
int main() {
	printf("%.3f\n", 1.0/3.0);//结果为0.333
	//printf("%d\n",2+3);//结果为5
	return 0;
}

引入数学库的方式

#include<stdio.h>
#include<math.h>
int main() {
	printf("%.4f\n", sqrt(9.0);//平方根,结果为3.0000
	return 0;
}

二:变量及输入

利用scanf进行变量的输入。


#include<stdio.h>
int main() {
    int a,b;
    scanf("%d%d",&a,&b);//输入两个整型变量,别漏掉&
	printf("%d\n", a*b+b-(a-c);
	return 0;
}

使用vs时可能会出现scanf返回值被忽略,可以参考大神博客:链接: vs中scanf返回值被忽略处理方法.

例题:输入底面半径r和高h,输出圆柱体的表面积,保留三位小数。
样例输入:
3.5 9
样例输出:
Area=274.889


#include<stdio.h>
#include<math.h>
int main() {
	const double pi = acos(-1.0);//尽量用const声明常数
	double r, h, s1, s2,s;
	scanf("%1f%1f", &h, &r);//使用%1f,而不是%f
	s1 = pi * r * r;
	s2 = 2*pi * r * h;
	s = s1 + 2.0*s2;
	printf("Area= %.3f\n", s);//程序只会将%后面的东西替换
	return 0;
}

三:顺序结构

例题:输入一个三位数,分离出他的百位、十位、个位,反转后输出。
样例输入
425
样例输出:
524

#include<stdio.h>
int main() {
	int n;
	scanf("%d",&n);
	printf("%d%d%d\n",n%10,n/10%10,n/100);//未解决问题:反转后0在开头。
	return 0;
}

特殊情况,如果输入数字的末尾是0,输出时不要零,不采用分支结构时

#include<stdio.h>
int main() {
	int n,m;
	scanf("%d",&n);
	m=n%10*100+n/10%10*10+n/100;
	printf("%d%d%d\n",m);
	return 0;
}

例题:输入两个整数a和b,交换二者的值,然后输出。
样例输入
824 16
样例输出:
16 824

//三变量法
#include<stdio.h>
int main() {
	int m, n,t;
	scanf("%d%d", &n,&m);
	t = m;
	m = n;
	n = t;
	printf("%d %d\n", n,m);
	return 0;
}
//两变量法,受局限,只能定义了加减法(异或)的可用,不推荐
#include<stdio.h>
int main() {
	int m, n;
	scanf("%d%d", &n,&m);
	m=m+n;
	n=m-n;
	m=m-n;
	printf("%d %d\n", n,m);
	return 0;
}
//竞赛所用黑盒思路
#include<stdio.h>
int main() {
	int m, n;
	scanf("%d%d", &n,&m);
	printf("%d %d\n", m,n);
	return 0;
}

四:分支结构

例题:已知鸡和兔的总数量为n,总腿数为m。输入n和m,依次输出鸡的数目和兔的数目。如果无解,则输出No answer。
样例输入
14 32
样例输出:
12 2
样例输入
10 16
样例输出:
No answer

#include<stdio.h>
int main() {
	int n, m, a, b;
	scanf("%d%d", &n, &m);
	a = 2 * n - m / 2;
	b= m / 2-n;
	if (a<0 || b<0||m%2==1)//腿的个数一定是偶数
		printf("No answer");
	else
		printf("%d %d\n", a, b);
	return 0;
}

在C语言中,单个整数也可以表示真假,其中0表示为假, 其他值表示为真。

例题:输入三个整数,从小到大排序后输出。
样例输入
20 7 33
样例输出:
7 20 33

#include<stdio.h>
int main() {
	int a, b, c;
	scanf("%d%d%d", &a, &b,&c);
	if (a <= b && b <= c) printf("%d %d %d", a, b, c);
	else if(a<=b&&c<=b&&a<=c) printf("%d %d %d", a, c, b);
	else if (b <= a && b <= c && a <= c) printf("%d %d %d",b,  a, c);
	else if (a <= b && c <= b && c <= a) printf("%d %d %d", c, a, b);
	else if (b <= a && c <= b && c <= a) printf("%d %d %d", c, b, a);
	else  
		printf("%d %d %d", b, c, a);
	return 0;
}
#include<stdio.h>
int main() {
	int a, b, c, t;
	scanf("%d%d%d", &a, &b, &c);
	if (b < a){
		t = a;a = b;b = t;
	}
	if (c < a) {
		t = a; a = c; c = t;
	}
	if (c < b) {
		t = b; b = c; c = t;
	}
	printf("%d %d %d", a, b, c);
	return 0;
}

五:习题

5.1平均数

输入三个整数,输出他们的平均值,保留三位小数。

#include<stdio.h>
int main() {
	int a, b, c;
	float ave;
	scanf("%d%d%d", &a,& b,& c);
	ave = (a + b + c) / 3.0;
	printf("%.3f\n", ave);
	return 0;
}

反思:
1.输入中要加&;
2.ave明显能取浮点数;
3.与浮点数相关的运算,必须要有浮点数的参加,所以不能除以3,而是3.0;

5.2温度

输入华氏温度f,输出对应的摄氏温度c,保留三位小数。其中c=5(f-32)/9.

#include<stdio.h>
int main() {
	float F, C;
	scanf("%f",& F);
	C = 5* (F - 32.0) / 9.0;
	printf("%.3f", C);
	return 0;
}

反思
scanf中小数%f,中间不能加点!

5.3连续和

输入正整数n,输出1+2+3+…+n的值。提示:目标是解决问题,而不是编写程序。

#include<stdio.h>
int main() {
	int n,sum;
	scanf("%d", &n);
	sum = (1 + n) *n/ 2;
	printf("%d\n", sum);
	return 0;
}

反思
在输入中一定要记得加上&!

5.4正弦和余弦(sin 和cos)

输入正整数n(n<360),输出n的度的正弦、余弦函数值。提示:使用数学函数。

#include<stdio.h>
#include<math.h>
int main() {
	int n;
	float value1,value2;
	scanf("%d", &n);
	const float pi = acos(-1.0);
	value1 = sin(n/180.0*pi);
	value2 = cos(n / 180.0 * pi);
	printf("%f %f", value1, value2);
	return 0;
}

反思
sin和cos函数中的数字是用弧度表示的,不是用角度表示的。

5.5打折

一件衣服95元,若消费满300元,可打85折。输入购买衣服件数,输出需要支付的金额(单位:元),保留两位小数。

#include<stdio.h>
#include<math.h>
int main() {
	const int price = 95;
	int n;
	float total_price;
	scanf("%d", &n);
	if (95 * n < 300)
		total_price = 95 * n;
	else 
		total_price = 95 * 0.85 * n;
	printf("%.2f", total_price);
	return 0;
}

5.6三角形

输入三角形3条边的长度值(均为正整数),判断是否能为直角三角形的3个边长。如果可以,则输出yes,如果不能,则输出no。如果根本无法构成三角形,则输出 not a triangle。

5.7年份

输入年份,判断是否为闰年。如果是,则输出yes,否则输出no。提示:简单的判断除以四的玉树是不够的。

原书作者提出的思考题:
1.int型整数的最小值和最大值是多少
2.double型浮点数能耐精确到多少位小数,或者本问法有什么问题
3.double型浮点数最大正数值和最小正数值分别是多少
4.逻辑符号&&、||和!的相对优先级是什么,如a&&b||c应该怎么理解
5.if(a)if(b)x++;else y++确切含义是什么,else和哪个if配套。
6.空格、tab和回车符的过滤

六:参考资料

刘汝佳. 算法竞赛入门经典[M]. 第2版. 北京 : 清华大学出版社, 2014

七:笔者注释

本文为学习《算法竞赛入门经典(第2版)》所做的学习笔记,仅作学习使用,切勿用作他途!如有侵权,联系立删。本文内容可能会有理解错误或遗漏,望乞指正,不胜感激!

猜你喜欢

转载自blog.csdn.net/guerbuzhang/article/details/108431959