首先是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;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。