某个题目:
若干任务。每个任务完成有一定时间。每个任务有上游任务,必须先完成上游任务才能去做该任务。可以同时进行最多n个任务。
输入格式为一行字符串:
h:[e,f,g]:2;e:[b]:6;f:[c]:6;g:[d]:6;b:[a]:5;c:[a]:5;d:[a]:5;a:[]:3/2
斜杠后的数字表示最多同时进行的任务数量。
分号隔开若干个任务描述。
每个任务描述组成方式:name:[name2,name3,name4,…]:time
中括号内为上游任务。
求完成这一系列任务需要的最小总时间(例程答案为22)
对于python而言直接使用split即可。
c++就不太方便了。现在的一个做法是转换成istringstream然后用getline
如:
void Split(const string s, vector<string>& output, const char ch) {
istringstream ss(s);
string tmp;
while(getline(ss, tmp, ch)) {
if (tmp == "") continue;
output.push_back(tmp);
}
}
sstream 还可以用来做格式转换(字符串与整型浮点型布尔型的转换)
template<class T>
void to_string(string & result,const T& t) {
ostringstream oss;//创建一个流
oss<<t;//把值传递如流中
result=oss.str();//获取转换后的字符转并将其写入result
}
不过c++11以后的自带的to_string函数已经很强大了。不需要自己定义了。
template<class out_type,class in_value>
out_type convert(const in_value & t){
stringstream stream;
stream<<t;//向流中传值
out_type result;//这里存储转换结果
stream>>result;//向result中写入值
return result;
}
注意iss oss的区别,前者只能是 iss>>xxxx, 后者只能是oss << xxxx。而ss两个方向都可以。
某个题目二:
有很多人。分为ABC三级。
每个C级人属于唯一一个B级人,每个B级人属于唯一一个A级人。
每个C级人有一个分数。B级人的分数等于其管理的全部C级人分数之和,
A级人的分数等于其管理的全部B级人分数之和。
输入内容:
value
Jacky,23
Lily,42
Cindy,87
Tomy,2
organization
Jone,Cris,Jacky
Jone,Troy,Lily
Ben,Andy,Cindy
Ben,Tim,Tomy
eof
解释:value说明了每个C级人的分数。organizatoin说明了从属关系,表示“A级,B级,C级”
希望输出内容为:
Ben<89>
-Andy<87>
--Cindy<87>
-Tim<2>
--Tomy<2>
Jone<65>
-Cris<23>
--Jacky<23>
-Troy<42>
--Lily<42>
先输出A级人,再输出其管理的B级人,加短横,再输出B级人管理的C级人,加两条短横。
每个人后用尖括号将分数包围着输出。
要按照得分降序排序。如果得分相同,则按照人名字母序升序排序。
【分析】需要自定义大小比较函数。
自定义比较函数。
比如sort函数传入的第三个参数即是自定义的比较函数。
https://blog.youkuaiyun.com/weixin_41588502/article/details/86620305
bool less_int(int a,int b){
return a<b;
}
sort(vec.begin(), vec.end(), less_int);
通常来说,排列时,从小到大就是less,即第一个小于第二个。升序。
第三个参数同时也可以是类里的仿函数:
struct cmp {
bool operator() (const Node & s1, const Node & s2) {
if(s1.x==s2.x) return s1.y<s2.y;
else return s1.x< s2.x;
}
};
sort(a,a+n,cmp());
也可以重载小于符号,然后不写第三个参数。
bool operator< (const Node& s1, const Node& s2) {
if(s1.x==s2.x) return s1.y<s2.y;//年龄相同时,按姓名小到大排
else return s1.x> s2.x; //从年龄大到小排序
}
sort(a,a+n);
对于优先队列这样的容器而言,自定义比较函数也有三种方式:
仿函数写法:
#include<queue>
#include<vector>
#include<iostream>
using namespace std;
struct node
{
int x, y;
node(int x,int y):x(x),y(y){}
};
struct cmp
{
bool operator()(node a,node b) // 其实是在重载()符号
{
if(a.x == b.x) return a.y >= b.y;
else return a.x > b.x;
}
};
int main()
{
priority_queue<node,vector<node>,cmp> pq; //带有三个参数的优先队列;
for(int i = 1; i <= 5; i++)
for(int j = 1; j <= 5; j++)
pq.push(node(i,j));
while(!pq.empty())
{
cout<<pq.top().x<<" "<<pq.top().y<<endl;
pq.pop();
}
return 0;
}
也可以重载小于符号
#include<queue>
#include<iostream>
using namespace std;
struct node
{
int x, y;
node(int x,int y):x(x),y(y){}
};
bool operator< (node a,node b)
{
if(a.x == b.x) return a.y >= b.y;
else return a.x > b.x;
}
int main()
{
priority_queue<node> pq; //只传node,但是node结构体的<运算符已被改变
}
重载也可以写在结构体定义里面(此时必须用const)
struct node
{
int x, y;
node(int x, int y):x(x),y(y){}
bool operator< (const node &b) const //写在里面只用一个b,但是要用const和&修饰,并且外面还要const修饰;
{
if(x == b.x) return y >= b.y;
else return x > b.x;
}
};
【总结】自定义比较函数建议全部采用结构体仿函数的形式。这样sort、容器都可以同时使用了。
再补充俩知识点:priority_queue对于“大小”的理解是反过来的!即使用<,但表示的是大顶堆!原因在于他是一个队列,队列的top其实是在数组最后面!即最大的在队列的顶部也就是这个数组的最后面。因此最前面的不一定是最小的(堆的性质)!
字符串按照字母序进行比较的函数:
逐位比较,越靠前则越大。
“abc" > "bbc"
前面完全相同,字符串越长就越大。
"abcc"> "abc"
大写排在小写的后面(这和阿斯克码顺序一致)
"abc">"Abc"
【其他】顺序容器与关联容器讲的不错的博客:
【输出保留小数位数】
#include <iomanip>
float a = 23.32323
cout<<setiosflags(ios::fixed)<<setprecision(2) << a;
// 或者直接输出
printf("%.2f", a);
补充:
如果采用python则:
import sys
for line in sys.stdin
lines = line.split(',')
# 或者
while True:
line = sys.stdin.readline()
lines = line.split(',')
if line == ''
break