2016年06月份CCF总结反思
总体感悟
- 第一题:太蠢,不谈
- 第二题:走了很大弯路,应该思考一下,第二题不难的
- 第三题:吐血了,STL一定要会用
- 第四题:很好的题目,如何把最小生成树和最短路径结合起来。
第四题题解
这个题目很好,特地写一下,即最小生成树和最短路径如何结合。
首先,要以Dijkstra为主,但是不同的是,要记录每个点的lastedge,比如有条边(1,2,10)被选中,那么点2的lastedge就是该边。
每次更新的时候,如果发现最短路径是相同的,那么看看lastedge是否比这条新边大,如果大那么lastedge就更新这条边。这就保证了最小生成树的产生。
细节收获
vector的总结反思
insert(v.begin()+pos,element)
erase(v.begin()+pos,element)
两个vector作比较
就不要去想什么奇技淫巧了。
int a_index = 0;
for (auto& x : b)
{
if(a_index == a_count) return;
...
}
map的总结反思
查找key值是否存在
if(map.count(key) > 0)
遍历输出
for (auto x = demo.begin(); x != demo.end(); ++x)
{
cout << x->first << " " << x->second << endl;
}
String的总结反思
其他样式转为string
采用to_string()即可。
去除末尾字符
- 首先要知道C++是利用记录字符串长度来知道如何结束,C是利用结尾为'\0'来看的。
- 因此不推荐str[str.size()-1] = '\0'这种写法,因为这样C++维护的字符串长度不变,会造成以后错误
- 推荐使用str.erase(str.end()-1);
字符串切割操作
就是利用getline(istream,string,char),就是不断的把istream放进string中,如果遇到char的那个字符,就停止。
template<typename Out>
void split(const std::string &s, char delim, Out result) {
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
*(result++) = item;
}
}
std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, std::back_inserter(elems));
return elems;
}
字符串忽略大小写比较
struct iequal
{
bool operator()(int c1, int c2) const
{
return std::toupper(c1) == std::toupper(c2);
}
};
bool iequals(const std::string& str1, const std::string& str2)
{
return std::equal(str1.begin(), str1.end(), str2.begin(), iequal());
}
字符串清空空格字符
bool isspace(int item)
{
if (item == ' ')
return true;
return false;
}
str.erase(remove_if(str.begin(), str.end(), isspace), str.end());
详细解释一下
bool isOdd(int item)
{
return (item - '0') % 2;
}
int main()
{
string test = "123456";
remove_if(test.begin(),test.end(),isOdd);
cout << test << endl;
// 输出结果为246456
// 可以看到它把所有不应该remove的元素都放在了前面
// 而他的返回值也顺理成章地是那些合法元素的最后位置+1,这个例子中就是3,其指向的是4,所以利用erase就可以把456都删除掉了
}
字符串去掉前导0
利用find_first_not_of即可
str.erase(0, min(str.find_first_not_of('0'), str.size()-1))
控制流
文件读入
freopen("in.txt","r",stdin)
读取一行然后进行内部操作
for (...)
{
string line;
getline(cin,line);
stringstream ss(line);
ss >> x >> y;
}
getline的问题
第一次getline前如果有scanf等读取输入的操作,需要在scanf之后使用cin.get()或cin.ignore()`