首先是vector : back()代表最后一个元素 end()表示最后一个元素之后的哨兵元素;
ios_base::sync_with_stdio(0); cin.tie(0), cout.tie(0);
关于algorithm 头文件的一些用法 double t = 3.33333333;
cout<<setprecision(8)<<t<<endl;
for_eachor_each(容器起始地址,容器结束地址,要执行的方法)


void printElem(int& elem)
{
  cout << elem << endl;
}
 
int main()
{
    int ia[]={0,1,2,3,4,5,6};
    for_each(ia,ia+7,printElem);

int find(int begin,int *end,int value)

int ia[]={0,1,2,3,4,5,6};
    int *i= find(ia,ia+7,9);//在整个数组中查找元素 9 
    int *j= find(ia,ia+7,3);//在整个数组中查找元素 3
    int *end=ia+7;//数组最后位置 
    if(i == end) 
       cout<<"没有找到元素 9"<<endl;
    else 

排序算法sort


char ch[20]="sdasdacsdasdas";
cout<<ch<<endl;
sort(ch,ch+14);
cout<<ch<<endl;

缺省是升序排序。sort中一个改变排序顺序的例子如下(降序)


#include<iostream>
#include<algorithm>
using namespace std;
bool cmp (const int a, const int b)
{
    return a > b;
}
int main()
{
    int data[5];
    for(int i = 0; i < 5; i++)
        cin >> data[i];
    sort(data, data + 5, cmp);
    return 0;
}

这个函数可以传两个参数或三个参数。第一个参数是要排序的区间首地址,第二个参数是区间尾地址的下一地址
有一个node类型的数组node arr[100],想对它进行排序:先按a值升序排列,如果a值相同,再按b值降序排列,如果b还相同,就按c降序排列。就可以写这样一个比较函数:
以下是代码片段:`
bool cmp(node x,node y)
{

 if(x.a!=y.a)  return x.a
 if(x.b!=y.b)  return x.b>y.b;
 return  return x.c>y.c;`


除此之外algorithm还有以下常用函数
max(x,y) 返回x y中的最大值,参数只能是两个,如果想比较x,y,z的最大值,可写为max(x,max(y,z))

min(x,y)同理,返回的是x,y中的最小值

abs(x)返回x的绝对值,x必须是整数 浮点数是math文件下的fabs

swap(x,y)用来交换x,y的值

reverse(it,it2)将数组指针在[it,it2)(不包括it2)之间的元素或容器的迭代器下在[it,it2)(不包括it2)范围的元素进行反转

fill()可以把数组或容器的某一段区间赋值为某个相同的值

匈牙利算法模板

#include <iostream>
#include <string>
#include<cstring>
using namespace std;
const int MNUM = 1005;
bool map[MNUM][MNUM];
int girl[MNUM]; int used[MNUM];
int n, m, e;
int cnt;



bool find(int i){

    for (int j =1;j<=m;++j)
    {
        if((map[i][j]==1)&&(used[j]==false)){
            used[j] = 1;
            if ((girl[j] == 0) || (find(girl[j]))){ girl[j] = i; return true; }    
        }

    }
    return false;
}
int ans;
int  main() {
    int x=0, y=0;
    cin >> n >> m >> e;
    for (int i=1;i<=e;i++)
    {
        cin >> x >> y;
        map[x][y] = 1;
    }

    for (int i=1;i<=n;++i)
    {
        memset(used, 0, sizeof(used));
        if (find(i))ans++;

    }

    cout << ans;
    return 0;

}

优先级队列的使用与kruskal(最小生成树算法)

#include <iostream>
#include <queue>
#include <algorithm>
 
using namespace std;
 
int p[500010]; //全局数组作为并查集
 
typedef struct Edge //定义边类型
{
    int u, v, w;
}Edge;
 
struct cmp //自定义优先级队列的比较函数
{
    bool operator()(const Edge &a, const Edge &b)
    {
        return a.w > b.w; //边权值小的优先级高
    }
};
 
int find(int x) //并查集查找根节点
{
    return p[x] == x ? x : p[x] = find(p[x]);
}
 
int main()
{
    int tmax = 0; //输出结果
    int n, m, root; //root只读入数据,后续程序与其无关
    cin >> n >> m >> root;
    for(int i = 0; i < n + 1; i++) //初始化并查集,注意题目结点顺序是从1开始而不是0
        p[i] = i;
    priority_queue<Edge, vector<Edge>, cmp> pq_e;
    for(int i = 0; i < m; i++) //读入边的数据并存储到优先级队列中
    {
        Edge e;
        int u, v, w;
        cin >> u >> v >> w;
        e.u = u, e.v = v, e.w = w;
        pq_e.push(e);
    }
    for(int i = n - 1; i > 0;) //由于MST的边数必定比结点数少1,故由此控制循环
    {
        Edge e = pq_e.top(); //队列头部元素一定是所有未访问边中权值最小的
        pq_e.pop();
        int u = e.u;
        int v = e.v;
        int ru = find(u);
        int rv = find(v);
        //在并查集中查找此边的两端点编号是否有共同的根,若有则说明若将此边纳入会出现回路,故应舍去
        if(ru == rv) continue;
        //没有则说明此边可以纳入MST中,由于题目的要求,最终的结果一定是最后纳入MST中边的权值
        //又因为优先级队列中的元素已按照最小权值优先的方式排列好了,因此可以不断进行覆盖操作
        //另外不要忘记将两端点所属集合合并到一起!
        else
        {
            p[ru] = rv; //合并集合
            tmax = e.w; //不断覆盖直至退出循环
            i--;
        }
    }
    cout << tmax;
    return 0;
}

并查集

#include <bits/stdc++.h>
using namespace std;
// ================= 代码实现开始 =================
const int N = 300005;
// Fanther:每个节点的父亲节点
// Rank:节点的秩(用于启发式合并)
int Father[N],Rank[N];

//查找节点x所在集合的根
int find(int x){
    return Father[x]==x?x:Father[x]=find(Father[x]);
}
// n:变量个数
// m:约束个数
// A:大小为m的数组,表示m条约束中的a
// B:大小为m的数组,表示m条约束中的b
// E:大小为m的数组,表示m条约束中的e
// 返回值:若能找出一种方案,返回"Yes";否则返回"No"
string getAnswer(int n, int m, vector<int> A, vector<int> B, vector<int> E) {
    for(int i=1; i<=n; ++i){
        Father[i] = i;
        Rank[i] = 0;
    }

     int cnt = 0;
     for(int i=0; i<m; ++i)  //将e=1的操作提到e=0的操作前
        if(E[i] == 1) {
           swap(E[i], E[cnt]);
           swap(A[i], A[cnt]);
           swap(B[i], B[cnt]);
           ++cnt;
     }
     for(int i=0; i<m; ++i){
        int setA = find(A[i]);
        int setB = find(B[i]);
        if(E[i] == 0){
            if(setA == setB){
                return "No";
            }
        }
        // E[i]==1 即 A[i]与B[i]有共同的父亲节点
        else{
            //在Union时把Rank更高的父亲节点作为根节点
            if(setA != setB){
                if(Rank[setA] > Rank[setB])
                    swap(setA,setB);
                // Rank[setB]的等级更高
                Father[setA] = setB;
                if(Rank[setA] == Rank[setB])
                    Rank[setB] +=1;
            }
        }
     }
     return "Yes";
}

// ================= 代码实现结束 =================

int main() {
    int T;
    for (scanf("%d", &T); T--; ) {
        int n, m;
        scanf("%d%d", &n, &m);
        vector<int> A, B, E;
        for (int i = 0; i < m; ++i) {
            int a, b, e;
            scanf("%d%d%d", &a, &b, &e);
            A.push_back(a);
            B.push_back(b);
            E.push_back(e);
        }
        printf("%s\n", getAnswer(n, m, A, B, E).c_str());
    }
    return 0;
}

最短路用pair 和数组记录

#include <bits/stdc++.h>
using namespace std;

// ================= 代码实现开始 =================
const int mo=911814;
typedef pair<int,int> pii;
const int N=100000;
int mind[N];
bool vis[N];
int num[N];
vector<pii> graph[N];
int flag[N];


priority_queue<pii,vector<pii>,greater<pii>> pq;
/* 请在这里定义你需要的全局变量 */
//找出最短路
void shortestPath(int n,int m,vector<int>U,vector<int> V,vector<int> C,int s){
//初始化
while(!pq.empty())
    pq.pop();
for(int i=1;i<=n;++i)
    graph[i].clear();
    memset(mind,127,sizeof(mind));
    memset(vis,0,sizeof(vis));
    memset(flag,0,sizeof(flag));
    memset(num,0,sizeof(num));
    //建图
    for(int i=0;i<m;++i){
            graph[U[i]].push_back(make_pair(V[i],C[i]));
            graph[V[i]].push_back(make_pair(U[i],C[i]));
    }
    mind[1]=0;
    pq.push(make_pair(mind[s],s));
    int u,v,c;
    while(!pq.empty()){
         u =pq.top().second;
        pq.pop();
        if(!vis[u]){
                vis[u]=1;
            for(vector<pii>::iterator it=graph[u].begin();it!=graph[u].end();++it){
                 v = it->first,c=it->second;
                if(mind[v]<mind[u]+c)
                    continue;
                mind[v]=mind[u]+c;
                pq.push(make_pair(mind[v],v));
            }
}
        }


}
//计算最短路数目
void numSort(){
 int u,v,c;
 pq.push(make_pair(mind[1],1));
    while(!pq.empty()){
       u =pq.top().second;
        pq.pop();
            for(vector<pii>::iterator it=graph[u].begin();it!=graph[u].end();++it){
                v = it->first,c=it->second;
                if(mind[v]<mind[u]+c)
                    continue;
                num[v]++;
                pq.push(make_pair(mind[v],v));


        }

    }
}

// 给定n个点m条边的无向图,求1到其余每个点的最短路的数目
// n:如题意
// m:如题意
// U:大小为m的数组,表示m条无向边中的一个端点
// V:大小为m的数组,表示m条无向边中的另一个端点
// C:大小为m的数组,表示m条无向边的长度
void getAnswer(int n, int m, vector<int> U, vector<int>V, vector<int>C) {
    /* 请在这里设计你的算法 */
    shortestPath(n,m,U,V,C,1);
    numSort();
    num[1]=1;
    for(int i=1;i<=n;++i){
        cout<<num[i]%mo<<endl;
    }

}

// ================= 代码实现结束 =================

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    vector<int> U, V, C;
    for (int i = 0; i < m; ++i) {
        int u, v, c;
        scanf("%d%d%d", &u, &v, &c);
        U.push_back(u);
        V.push_back(v);
        C.push_back(c);
    }
    getAnswer(n, m, U, V, C);
    return 0;
}

循环节-简单kmp使用:

#include <cstdio>
#include <cstring>
#include<iostream>
#include <queue>
using namespace std;
#define maxl 1000000
/* =========== 代码实现开始 =========== */

int next1[maxl];
char s[maxl + 10];


// s, len: 输入字符串(题目中的c)及长度
// 返回值:题目中 a 串的最短长度
int solve(char *s, int len)
{
        int j=-1,i=0;
        next1[0]=-1;
        while(i<len){
   if(j==-1||s[i]==s[j]){
        i++,j++;
        next1[i]=j;
}else

    j=next1[j];

}

    return i-j;

  }

/* =========== 代码实现结束 =========== */



int main()
{
    int len;
    scanf("%d%s", &len, s);
    printf("%d\n", solve(s, len));
    return 0;
}

小粽家里有一块地,地上有 n个木桩。小粽家的地可以看作是一个平面,并且小粽知道每个木桩的坐标 小粽很喜欢四边形,现在她想从这些木桩中选出 4
个来围成一个四边形(这个四边形为简单多边形,即每条边不能和自己相交,但不一定要为凸四边形),并使得这个四边形的面积最大。请你帮小粽算出这个最大值是多少。

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps=1e-8,pi=acos(-1);
int cmp(double x)
{
    if (x>eps) return 1;
    if (fabs(x)<=eps) return 0;
    return -1;
}
struct Vector
{
    double x,y;
    bool operator < (const Vector &v) const
    {
        return cmp(x-v.x)==-1;
    }
    void rd()
    {
        scanf("%lf%lf",&x,&y);
    }
    Vector operator + (const Vector &v) const
    {
        return (Vector){x+v.x,y+v.y};
    }
    Vector operator - (const Vector &v) const
    {
        return (Vector){x-v.x,y-v.y};
    }
}a[10010],f[10010];
typedef Vector Point;
double dot(Vector v,Vector u)
{
    return v.x*u.x+v.y*u.y;
}
double cross(Vector v,Vector u)
{
    return v.x*u.y-v.y*u.x;
}
double len(Vector v)
{
    return sqrt(dot(v,v));
}
double size(Point a,Point b,Point c)
{
    return fabs(cross(b-a,c-a))/2;
}
struct Line
{
    Point p;
    Vector v;
}l1;
double dis(Point p,Line l)
{
    return fabs(cross(l.v,p-l.p))/len(l.v);
}
int n,m,mm;
int main()
{
    double ans=0;
    scanf("%d",&n);
    for (int i=1;i<=n;i++) a[i].rd();
    sort(a+1,a+n+1);
    f[0]=a[1];
    m=1;
    for (int i=2;i<=n;i++)
    {
        while (m>1&&cmp(cross(f[m-1]-f[m-2],a[i]-f[m-2]))>=0) m--;
        f[m++]=a[i];
    }
    mm=m;
    for (int i=n-1;i;i--)
    {
        while (m>mm&&cmp(cross(f[m-1]-f[m-2],a[i]-f[m-2]))>=0) m--;
        f[m++]=a[i];
    }
    m--;
    for (int i=0;i<m;i++)
        for (int j=(i-2+m)%m,x=(i-1+m)%m,nex=(x-1+m)%m,y=(j-1+m)%m,ney=(y-1+m)%m;
            j!=(i+1)%m;j=(j-1+m)%m)
            {
                while (nex!=j&&cmp(size(f[i],f[j],f[nex])-size(f[i],f[j],f[x]))==1)
                    x=nex,nex=(x-1+m)%m;
                while (ney!=j&&cmp(size(f[i],f[j],f[ney])-size(f[i],f[j],f[y]))==1)
                    y=ney,ney=(y-1+m)%m;
                ans=max(ans,size(f[i],f[j],f[x])+size(f[i],f[j],f[y]));
            }
    printf("%.3f\n",ans);
}

二叉搜索树首先数组递归版

struct Node 
{
    int val;
    int l;
    int r;
    Node(int V,int L ,int R):val(V),l(L),r(R){
    };
}node[2005];
int insert(int val, int x){
    if (x==0)
    {
        cnt++;
        x = cnt;
        node[x].val = val;
        node[x].l = node[x].r = 0;
        return x;
    }
    if(val<node[x].val){
        node[x].l=insert(val, node[x].l);
        //标记行
    }
    else {
        node[x].r = insert(val, node[x].r);
        //标记行
    }
    return x;//标记行2
}

/*此处保留一个疑问: 当标记行2 的语句放在俩标记行位置时和上述语句的执行效果会有区别吗?
当然也可借鉴下面这一套二叉搜索树模板(由于需求问题未完全实现)*/

struct TreeNode
{
    int key;
    TreeNodePosion p;
    TreeNodePosion l;
    TreeNodePosion r;
    TreeNode(int val) :key(val), l(NULL), r(NULL), p(NULL) {};
};
struct  Tree
{
    TreeNodePosion root;
};
TreeNodePosion tree_search(TreeNodePosion x, int k) {
    if (x == NULL || x->key == k)return x;
    if (x->key < k)tree_search(x->l, k);
    if (x->key > k)tree_search(x->r, k);
}
TreeNodePosion find_max(TreeNodePosion x) {
    while ((x->r) != NULL)x = x->r;
    return x;
}
TreeNodePosion find_min(TreeNodePosion x) {
    while ((x->l) != NULL)x = x->l;
    return x;
}

TreeNodePosion find_succ(TreeNodePosion x) {
    if (x->r != NULL)return find_min(x->r);
    TreeNodePosion p = x->p;
    TreeNodePosion y = x;
    while (p != NULL)
    {
        if (p->l == y)break;
        y = p;
        p = p->p;
    }
    return p;
}
TreeNodePosion find_pre(TreeNodePosion x) {
    if (x->l != NULL)return find_max(x->l);
    TreeNodePosion p = x->p;
    TreeNodePosion y = x;
    while (p != NULL)
    {
        if (p->r == y)break;
        y = p;
        p = p->p;
    }
    return p;
}

void insert(TreeNodePosion& root, int k) {
    if (root == NULL) { root = new TreeNode(k); return; }
    TreeNodePosion tem = root;
    TreeNodePosion tem1 = tem;
    while (tem != NULL)
    {
        tem1 = tem;
        if (tem->key > k) { tem = tem->l; }
        else if (tem->key < k) { tem = tem->r; }
        else
        {
            return;
        };
    }
    TreeNodePosion new_node = new TreeNode(k);
    new_node->p = tem1;
    if (k < tem1->key) { tem1->l = new_node; }
    else if (k > tem1->key) {
        tem1->r = new_node;
    }
}


void pre_order(TreeNodePosion p) {
    if (p != NULL)
    {
        cout << p->key << ' ';
        pre_order(p->l);
        pre_order(p->r);
    }
}


void in_order(TreeNodePosion p) {

    if (p != NULL) {
        in_order(p->l);
        cout << p->key << ' ';
        in_order(p->r);
    }
}


void post_order(TreeNodePosion p) {
    if (p != NULL) {
        post_order(p->l);
        post_order(p->r);
        cout << p->key << ' ';
    }
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int n; TreeNodePosion root = NULL;
    cin >> n; int k;
    while (n--)
    {
        cin >> k;
        insert(root, k);
    }
    pre_order(root); cout << '\n';
    post_order(root);

    return 0;
}

hhhhhh
1 声望0 粉丝