[读书笔记]《算法竞赛入门经典》第1章

书名:算法竞赛-入门经典 第2版
作者:刘汝佳
类别:读书笔记

前言

前言之中比较重要的是作者对整本书的架构安排:

  • 第一部分是语言篇(第1-4章)
  • 第二部分是算法篇(第5-8章)
  • 第三部分是竞赛篇(第9-11章)
  • 全新的第12章是在《算法竞赛入门经典----训练指南》的基础上补充少量知识与大量精彩例题

第1章 程序设计入门

1.1 算术表达式

#include <stdio.h>
#include <math.h>

int main(int argc, const char * argv[]) { 
    printf("%d\n", 1+2);
    return 0;}

Experiment 1 - 4:

Expressionoutput
1+23
3-4-1
5*630
8/42
8/51
-8/5-1

此处需要注意整数相除可能会有 Truncation 的现象出现。


#include <stdio.h>
#include <math.h>

int main(int argc, const char * argv[]) { 
    printf("%1f\n", 8.0/5.0);
    return 0;}

Experiment 5 - 7:

Statementoutput
printf("%.1f\n", 8.0/5.0)1.6
printf("%.2f\n", 8.0/5.0)1.60
printf("%.1f\n", 8/5)0.0
printf("%d\n", 8.0/5.0)-272632504

尽管已经学过C很久了,我也没有想到实验7居然会得出这个结果,这是为什么呢?

Learning Points:

  • Output integers by %d, output real numbers by %f
    *f stands for floating point
  • Integer/Integer = Integer; Floating Point/ Floating Point = Floating Point

1.2 变量及其输入

Learning Points:

语法相关:

  • How to read keyboard input?
    scanf 中的占位符(例如%d, %f)和变量应该一一对应,而且每个变量之前必须要加“&”。
  • 尽量用const 声明常数。

竞赛相关:

  • 在竞赛当中,输入前不要打印提示信息,输出后应该立即终止程序。
  • 每一行输出都应该以回车符 \n 结束,包括最后一行。除非特别说明,行首不应该有空格。

有关赋值(Assignment) 和 printf 函数的使用不再赘述。


1.3 顺序结构程序设计(Sequential Program)

如何交换两个变量(swapping)?

  1. 三变量法
  2. 算术法 (第8页程序1-9)
  3. 直接输入输出

Learning Points:

竞赛相关:

  • 可以用手工模拟的方式理解程序的执行方式,那么模拟的具体写什么呢?重点在于记录每条语句执行之后各个变量的值。

1.4 分支结构程序设计(Branching)

Learning Points:

语法相关:

  • if 语句的基本格式为 (只有一条语句时,花括号“{ }”可以省略):
    if (condition) {
    	statement 1;
    	...
    }
    else {
    	statement 2.
    	...
    }
    
  • condition 可以是逻辑表达式(logical expression) 也可以是整数值。注意condition是整数值的时候,0=false, 其他值=true
  • 如果有多个并列、情况不交叉的condition需要一一处理,可以用else if 语句。
  • 注释可以使用 // 或者 /* */

竞赛相关:

  • 在竞赛当中,我们设计的程序应该对任何输入都有效,而不仅仅是样例数据。Make sure program works beyond given test cases.

1.5 注解与习题

1.5.1 C语言、C99、C11 以及其他

C语言标准:设计之初是为了防止同样的程序被不同的编译器编译成截然不同的指令
读者需要注意的是,应当把前4章的内容当成是在学习C++当中与C相兼容的部分。

1.5.2 数据类型与输入格式

#include <stdio.h>
#include <math.h>

int main(int argc, const char * argv[]) {
    
    int a = 11111*11111;
    printf("%d\n", a);
    return 0;
}

注:下列所有实验的输出当中,printf 函数中的占位符统一与变量a相匹配。
int a -> printf("%d\n", a);
double a -> printf("%.1f\n", a);

实验expressionoutputremarks
A1.1int a = 11111*11111123454321
A1.2int a = 111111*1111111-539247567overflow in expression
A1.3int a = 111111111*1111111111653732529overflow in expression
A2.1double a = 11111*11111123454321.0
A2.2double a = 111111*111111-539247567.0overflow in expression
A2.3double a = 111111111*1111111111653732529.0overflow in expression
A3.1double a = sqrt(-11)nan系统没有报错
A3.2int a = sqrt(-11)-2147483648系统没有报错
A4.1double a = 1.0/0.0inf
A4.2double a = 0.0/0.0nan
A4.3int a = 1.0/0.0-272632320
A4.4int a = 0.0/0.0-272632320
A5.1int a = 1/0-272632320Division by zero is undefined
A5.2double a = 1/00.0Division by zero is undefined

从上列实验可以观察出:

  • intdouble 都不可以处理较大的数
  • 在做不正确的计算时,double时常会返回 nan (not a number) 或者 inf (infinity)

#include <stdio.h>
#include <math.h>

int main(int argc, const char * argv[]) {
    
    int a, b;
    scanf("%d%d", &a, &b);
    printf("%d %d\n", a ,b);
    return 0;
}
实验inputoutputremarks
B112 212 2空格分离
B212 212 212 2 不同行
B312 212 212 和 2 前面后面有大量空格、tab、甚至空行
B4.112 s12 0空格分离
B4.212 s12 012 2 不同行
B4.312 s12 012 和 2 前面后面有大量空格、tab、甚至空行

1.5.3 习题

本章习题过于简单,不再赘述。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值