【4号做了一下PAT的代码仓库,我像一个傻子开着vs提交git,结果一直提示commit failed,用shell一个个文件add才发现是自己现在正在写的题的文件被锁住了=/=,PAT教给了我很多,比如一定不能变成一个弱智。 】
1.Dijkstra
void Dijkstra() {
while (!visited[D]) {
int v = -1, min = INF;
for (int i = 0; i < N; i++) {
if (!visited[i] && dis[i] < min) {
v = i;
min = dis[i];
}
}
if (v == -1) return;//未联通
visited[v] = true;//访问该点
for ( edge&e : graph[v] ) {
if (!visited[e.v] && dis[e.v] > dis[v] + e.dis ){
dis[e.v] = dis[v] + e.dis;
cost[e.v] = cost[v] + e.cost;
pathLast[e.v] = v;
}
else if(dis[e.v] == dis[v]+ e.dis && cost[e.v]> cost[v] + e.cost){//花费更少
cost[e.v] = cost[v] + e.cost;
pathLast[e.v] = v;
}
}
}
}
2.Dijkstra所需数据结构
struct edge {
int v,dis,cost;//末端结点、距离、权重
edge( int _v, int _d, int _c) {
v = _v;
dis = _d;
cost = _c;
}
};
vector<vector<edge> > graph(505);
int dis[505], cost[505], pathLast[505];//起点到该点的距离,起点到该点的最小权重,起点到该点的父节点
bool visited[505] = {false};
3.Dijkstra初始化
for (int i = 0; i < M; i++) {
scanf("%d %d %d %d", &a, &b, &c, &d);
graph[a].push_back(edge(b, c, d));
graph[b].push_back(edge(a, c, d));
}
fill(dis, dis + N, INF);
fill(cost, cost + N, INF);
dis[S] = cost[S] = 0;
Dijkstra();
4.回文串的常用函数
string.substr(pos,n);
reverse(string.begin(),string.end());
5 .大数运算的结果对1000000007取模 防止溢出
6. getchar()吃掉getline()前面的回车
7.几个基础排序:
直接插入排序的算法思路:(1) 设置监视哨r[0],将待插入记录的值赋值给r[0];(2) 设置开始查找的位置j;(3) 在数组中进行搜索,搜索中将第j个记录后移,直至r[0].key≥r[j].key为止;(4) 将r[0]插入r[j+1]的位置上。
归并操作(merge),也叫归并算法,指的是将两个顺序序列合并成一个顺序序列的方法。如 设有数列{6,202,100,301,38,8,1}初始状态:6,202,100,301,38,8,1第一次归并后:{6,202},{100,301},{8,38},{1},比较次数:3;第二次归并后:{6,100,202,301},{1,8,38},比较次数:4;第三次归并后:{1,6,8,38,100,202,301},比较次数:4;总的比较次数为:3+4+4=11;逆序数为14;
(4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
8.格式检测
sscafn(formalstr,"%format",&deststr);
读取指定格式的数据sprintf(deststr,"%format",formalstr);
将指定格式数据写入字符串对比两个的结果 即可(compare或逐位,不要用等号)
9.判断是素数的模板
bool isprime(int a) {
if (a == 1) return false;
for (int i = 2; i <= sqrt(a); i++) {
if (a % i == 0) return false;
}
return true;
}
10.判断是数字或字母时,可用cctype的
isalnum(string)
0 条评论