【算法竞赛入门经典】读书笔记

前言

寒假期间准备一下练一下OJ,对于我这个小菜鸟来说,打稳基础很是关键。听说过【算法竞赛入门经典】的大名,加上自己学习的是 C++ ,而这本书用的是 C ,多学一门语言也是不错的。因此决定每天最少看一章节。祝我成功,加油。


第一章

  • 输入输出
    C 语言的输入都是类似于占位符。
    pirntf ("%.2f" ,b);//这里是保留b的二位小数,四舍五入。
    scanf ,输入浮点数的时候 %lf 注意是 L 的小写 l,不是1。我试了好半天才发现不同。
    scanf("%lf%lf",&a,&b); // 注意后面的一定要加上 & 符号。

在算法竞赛中,每行输出均应以回车符结束,包括最后一行。除非特别说 明,每行的行首不应有空格,但行末通常可以有多余空格。

程序的设计中肯定会用到数学知识,比如 : 两个偶数的和一定是 偶数。(鸡兔同笼)

总结

第一章是非常基础的知识,唯一令我感到惊讶的是 printf 函数保留小数的功能。其余的暂时没发现比 C++ 好到哪里。


第二章

循环

当前流行的竞赛平台中,int都是
32位整数,范围是-2147483648~2147483647。
long long 即可解决问题,其范围是-2 ^63 ~2 ^63 -1

  • 10 ^-6 用 1e-6 表示

可以使用time.h和clock()函数获得程序运行时间。常数
CLOCKS_PER_SEC和操作系统相关,请不要直接使用clock()的返回值,而应总是除以
CLOCKS_PER_SEC。

25!末尾有6个0

  • 碰到那种未指明有多少数据量的。利用 cin 的返回值 或者 scanf 的返回值
			while(cin>>a);
			while(scanf("%d",&a)==1)  //C 语言中,scanf 的返回值是正确输入的数目。本例中还有一个 a 因此返回值为1

文件的输入输出
编程中读取文件内容,大量应用于测试数据较多的情况下

使用文件最简单的方法是使用输入输出重定向,只需在main函数的入口处加入以下两条语句:
freopen(“input.txt”, “r”, stdin);
freopen(“output.txt”, “w”, stdout);
上述语句将使得scanf从文件input.txt读入,printf写入文件output.txt。

数组和字符串

数组的复制操作,因为没有经过什么系统的训练。因此字符串的复制我都是用 for 循环赋值。但是看了书后,学习到了 memcpy 。需要头文件 #include < string > (C++版)

memcpy(目的数组,起始数组,字节长)
举个栗子,从 int 型数组 a 复制 k 个数字到 int 型数组 b ,这样复制 memcpy(b,a,sizeof(int) *k)
全部复制使用 memcpy(b,a,sizeof(a));

数组清零

memcpy(a ,0,sizeof(a))

字符数组

字符串处理是常用的并且比较繁琐的一项基础能力。在 C 语言中,字符串就是字符数组(与 C++ 不同,C++ 有专门的string类)可以像处理普通数组那样处理字符串。

字符数组的读取

scanf("%s",s); //注意: s 为字符数组,前面没有 & 符号。 这样的读取遇到空格会停下来。

由于字符串的本质是数组,它也不是“一等公民”,只能用
strcpy(a, b),
strcmp(a, b),
strcat(a, b)
来执行“赋值”、“比较”和“连接”操作,而不能用“=”、“==”、 “<=”、“+”等运算符。

  • 对于strcmp来说:
    设这两个字符串为str1,str2,
    若str1=str2,则返回零;
    若str1<str2,则返回负数;
    若str1>str2,则返回正数。
    strcmp 示例

    • strcat(char *,const char * ) //连接操作不言而喻

第四章

函数与递归

正式进入函数与递归的课程。
** C语言的结构体**

typedef struct {double x,y;} Point;
//其实按照 C++ 的写法也没问题

素数模板

int is_prime(int n)
{
	if( n <= 1) return 0;
	int m=floor(sqrt(n)+0.5);  // floor() 函数为向下取整,这种写法实现了四舍五入
	for( int  i = 2  ;  i<=m  ; i++)
	if( n % i == 0) return 0;
	return 1;
}
  • 尽量少使用指针,尽管他十分的巧妙。
  • 以数组为参数调用函数时,实际上只有数组首地址传递给了函数,需要另
    加一个参数表示元素个数。除了把数组首地址本身作为实参外,还可以利用指针加减法把其他元素的首地址传递给函数。无法使用 sizeof(数组名) 来获得数组的大小。

递归

递归:自己调用自己。


第五章 C++

又一次来到了 C++ 的世界,主要介绍 C++ 面向竞赛的一面。

  • 使用 swap函数时,记得加上头文件 #include< algorithm>
    在 C 语言中,strlen 是一笔不小的开销。相比于 C++ ,用 C 语言去处理字符串并不方便。

虽然string和sstream都很方便,但string很慢,sstream更慢,应谨慎使用

某个数字首次出现的位置=lower_bound(起始地址,结束地址,查找数)-起始地址(int类型)

stringstream
这个类在之前一直用来转化类型,如果使用一个对象对此转换,那么记住要clear() ,这里是它的另一种用途:stringstream 类具有压缩空格的功能。

#include <iostream>
#include <set>
#include <sstream>
#include <string>
using namespace std;
int main()
{
	string a, b;
	cin >> a;
	cout << a << endl;
	for (int i = 0; i < a.length(); i++)
	{
		if(!isalpha(a[i]) )
			a[i]=' ';
	}
	stringstream ss(a);
	ss >> b;
	cout << b << endl;
/*
如果 a输入为“........aaaaa”
那么 b 输出为 aaaaa
不包含空格!
*/
}

set 与 map

set 类,集合类的特点是内部没有相同的元素,并且具有按照从小到大排序的功能(内部已经排好了)。

方法函数
定义set < T> 名称
插入名称.insert(dsa)
  • map 也具有从小到大排序的功能。
#include <iostream>
#include <map>
using namespace std;
int main()
{
	map<string, int> ss;
	ss["dddcc"] = 4;
	ss["accc"] = 14;
	ss["c41"]=0;
	for (auto it = ss.begin(); it!= ss.end(); it++)
	{
		cout << it->second << endl;
	}
}

/*
14
0
4

若要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口...
*/

优先队列

优先队列
是一种抽象数据类型(Abstract Data Type,ADT),行为有些像队列,但先出
队列的元素不是先进队列的元素,而是队列中优先级最高的元素,这样就可以允许类似
于“急诊病人插队”这样的事情发生。

pirority_queue 默认的是“数值越小的优先级别越低”,如果想“数值越小的优先级别越高”那么需要定义

priority_queue<int,vector< int>,greater< int> > 变量名

这里书上插入了一道《丑数题》,题目很有意思。另写了一篇博客

应用:大整数类

暂时看不懂。。


第六章 数据结构基础

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值