蓝桥杯学习记录
一、测试练习:
问题名称:时间转换
问题描述:
给定一个以秒为单位的时间t,要求用“H:M:S”的格式来表示这个时间。H表示时间,M表示分钟,而S表示秒,它们都是整数且没有前导的“0”。例如,若t=0,则应输出是“0:0:0”;若t=3661,则输出“1:1:1”。
输入格式:
输入只有一行,是一个整数t(0<=t<=86399)。
输出格式:
输出只有一行,是以“H:M:S”的格式所表示的时间,不包括引号。
样例输入:
5436
样例输出:
1:30:36
解题思路:
重复做取余和整除运算即可。
代码:
#nclude <iostream>
using namespace std;
//时间转换
int main()
{
int t;
cin>>t;
int S,M,H;
S = t % 60;
t /= 60;
M = t % 60;
t /= 60;
H = t % 60;
cout<<H<<':'<<M<<':'<<S;
}
二、视频学习:
学习链接:https://www.bilibili.com/video/BV1jE411g76D?p=9&t=2200
学习内容:映射
映射是指两个集合之间的元素的相互对应的关系。通俗地说,就是一个元素对应另外一个元素。比如有一个姓名的集合{“Tom”,“Jone”,“Mary”},班级集合{1,2}。姓名与班级之间可以有如下的映射关系:
class(“Tom”) = 1, class(“Jone”) = 2,class(“Mary”) = 3
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7aGKLTbY-1615017449250)(C:\Users\86184\AppData\Roaming\Typora\typora-user-images\image-20210306150740717.png)]
构造一个映射
在C++中,构造一个map的语句为:map<T1, T2> m; 这样就定义了一个名为m的从T1类型到T2类型的映射。初始的时候m是空映射。
插入一对映射
在C++中通过insert()函数向集合中插入一个新的映射,参数是一个pair。
pair是一个标准库类型,定义在头文件utility中。可以看成是有两个成员变量first和second的结构体,冰鞋重载了<运算符(先比较first大小,如果一样再比较second)。当我们创建一个pair时,必须提供两个类型。
比如,定义一个保存string和int的pair:
pair<string, int> p;
make_pair(v1, v2)函数返回由v1和v2初始化的pair,类型可以从v1和v2的类型推断出来。
我们向映射中加入新映射对的时候就是通过插入pair来实现的。如果插入的key之前已经存在了,将不会用插入的新的value替代原来的value,也就是这次插入是无效的。
#include <iostream>
#include <map>
#include <utility>
using namespace std;
int main()
{
map<string, int>dict; //dict是一个string到int的映射,存放每个名字对应的班级号,初始时为空
dict.insert(make_pair("Tom",1));//{"Tom"->1}
dict.insert(make_pair("Jone",2));//{"Tom"->1,"Jone"->2}
dict.insert(make_pair("Mary",3));//{"Tom"->1,"Jone"->2,"Mart"->1}
return 0;
}
访问映射
在C++中访问映射和数组一样,直接用**[]就能访问。比如dict[“Tom”]就可以获取"Tom"的班级了。(如果没有对Tom做过映射的话,此时访问dict[“Tom”],系统将会自动为"Tom"生成一个映射,其value**为对应类型的默认值,比如int的默认值是0, string的默认值是空字符串)。
并且之后可以再给映射赋予新的值,比如dict[“Tom”] = 3,这样为我们提供了另一种方便的插入手段。实际上,我们常常通过下表访问的方式来插入映射,而不是通过用,insert插入一个pair来实现。
#include <iostream>
#include <map>
#include <utility>
using namespace std;
int main()
{
map<string, int>dict; //dict是一个string到int的映射,存放每个名字对应的班级号,初始时为空
dict["Tom"] = 1;//{"Tom"->1}
dict["Jone"] = 2;//{"Tom"->1,"Jone"->2}
dict["Mary"] = 1;//{"Tom"->1,"Jone"->2,"Mart"->1}
cout << "Mary is in class " << dict["Mary"]<<endl;
cout << "Tom is in class " << dict["Tom"] << endl;
return 0;
}
判断关键字是否存在
在C++中,想知道某个关键字是否被映射过,可以直接用**count()**函数。如果关键字存在,返回1,否则返回0.
#include <iostream>
#include <map>
#include <utility>
using namespace std;
int main()
{
map<string, int>dict; //dict是一个string到int的映射,存放每个名字对应的班级号,初始时为空
dict["Tom"] = 1;//{"Tom"->1}
dict["Jone"] = 2;//{"Tom"->1,"Jone"->2}
dict["Mary"] = 1;//{"Tom"->1,"Jone"->2,"Mart"->1}
if (dict.count("Mary")){
cout << "Mary is in class " << dict["Mary"] << endl;
} else {
cout << "Mary has no class " << endl;
}
return 0;
}
遍历映射
map的迭代器定义和set差不多,map<T1, T2>::iterator it 就定义了一个迭代器,其中T1、T2分别是key 和 value的类型。
C++通过迭代器可以访问集合中的每个元素。这里迭代器指向的元素是一个pair,有first 和 second 两个成员变量, 分别代表映射的key 和 value。
我们用 ->运算符来获取值, **it -> first **和 (*it).first的效果是一样的,就是获取迭代器 it 指向的pair 里 first 成员的值。
#include <iostream>
#include <map>
#include <utility>
using namespace std;
int main()
{
map<string, int>dict; //dict是一个string到int的映射,存放每个名字对应的班级号,初始时为空
dict["Tom"] = 1;//{"Tom"->1}
dict["Jone"] = 2;//{"Tom"->1,"Jone"->2}
dict["Mary"] = 1;//{"Tom"->1,"Jone"->2,"Mart"->1}
for (map<string, int>::iterator it = dict.begin(); it != dict.end(); it++){
cout<< it->first<<" -> "<<it->second<<endl; //first是关键字,second是对应的值
}
return 0;
}
注意,在C++中遍历map是按照从小到大遍历的
清空
c++中只需要调用clear() 函数就可清空 map 和其占用的内存。
总结
函数 | 功能 | 时间复杂度 |
---|---|---|
insert | 插入一对映射 | O(log n) |
count | 判断关键字是否存在 | O(log n) |
size | 获取映射对个数 | O(1) |
clear | 清空 | O(n) |
------------ | ---------- |
| insert | 插入一对映射 | O(log n) |
| count | 判断关键字是否存在 | O(log n) |
| size | 获取映射对个数 | O(1) |
| clear | 清空 | O(n) |