数据结构
@并查集(How Many Tables)
#include<bits/stdc++.h>
using namespace std;
const int maxn=1000+8;
int pre[maxn];
int find_pre(int x)
{
if(x==pre[x])
{
return x;
}
else
{
pre[x]=find_pre(pre[x]);
}
}
void join(int x,int y)
{
int a=find_pre(x);
int b=find_pre(y);
if(a!=b)
{
pre[b]=a;
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
pre[i]=i;
}
for(int i=0;i<m;i++)
{
int x,y;
cin>>x>>y;
join(x,y);
}
int res=0;
for(int i=1;i<=n;i++)
{
if(pre[i]==i)
{
++res;
}
}
cout<<res<<endl;
}
return 0;
}
@kmp算法
/*
|kmp算法|
|字符串匹配|
*/
void getnext(char str[maxn], int nextt[maxn]) {
int j = 0, k = -1;
nextt[0] = -1;
while (j < m) {
if (k == -1 || str[j] == str[k]) {
j++;
k++;
nextt[j] = k;
}
else
k = nextt[k];
}
}
void kmp(int a[maxn], int b[maxn]) {
int nextt[maxm];
int i = 0, j = 0;
getnext(b, nextt);
while (i < n) {
if (j == -1 || a[i] == b[j]) { // 母串不动,子串移动
j++;
i++;
}
else {
// i不需要回溯了
// i = i - j + 1;
j = nextt[j];
}
if (j == m) {
printf("%d\n", i - m + 1); // 母串的位置减去子串的长度+1
return;
}
}
printf("-1\n");
}
计算几何
@向量基本用法
struct node {
double x; // 横坐标
double y; // 纵坐标
};
typedef node Vector;
Vector operator + (Vector A, Vector B) { return Vector(A.x + B.x, A.y + B.y); }
Vector operator - (Point A, Point B) { return Vector(A.x - B.y, A.y - B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x / p, A.y*p); }
double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; } // 向量点乘
double Length(Vector A) { return sqrt(Dot(A, A)); } // 向量模长
double Angle(Vector A, Vector B) { return acos(Dot(A, B) / Length(A) / Length(B)); } // 向量之间夹角
double Cross(Vector A, Vector B) { // 叉积计算 公式
return A.x*B.y - A.y*B.x;
}
Vector Rotate(Vector A, double rad) // 向量旋转 公式 {
return Vector(A.x*cos(rad) - A.y*sin(rad), A.x*sin(rad) + A.y*cos(rad));
}
Point getLineIntersection(Point P, Vector v, Point Q, Vector w) { // 两直线交点t1 t2计算公式
Vector u = P - Q;
double t = Cross(w, u) / Cross(v, w); // 求得是横坐标
return P + v*t; // 返回一个点
}
@求多边形面积
node G[maxn];
int n;
double Cross(node a, node b) { // 叉积计算
return a.x*b.y - a.y*b.x;
}
int main()
{
while (scanf("%d", &n) != EOF && n) {
for (int i = 0; i < n; i++)
scanf("%lf %lf", &G[i].x, &G[i].y);
double sum = 0;
G[n].x = G[0].x;
G[n].y = G[0].y;
for (int i = 0; i < n; i++) {
sum += Cross(G[i], G[i + 1]);
}
// 或者
//for (int i = 0; i < n; i++) {
//sum += fun(G[i], G[(i + 1)% n]);
//}
sum = sum / 2.0;
printf("%.1f\n", sum);
}
system("pause");
return 0;
}
@判断线段相交
node P[35][105];
double Cross_Prouct(node A,node B,node C) { // 计算BA叉乘CA
return (B.x-A.x)*(C.y-A.y)-(B.y-A.y)*(C.x-A.x);
}
bool Intersect(node A,node B,node C,node D) { // 通过叉乘判断线段是否相交;
if(min(A.x,B.x)<=max(C.x,D.x)&& // 快速排斥实验;
min(C.x,D.x)<=max(A.x,B.x)&&
min(A.y,B.y)<=max(C.y,D.y)&&
min(C.y,D.y)<=max(A.y,B.y)&&
Cross_Prouct(A,B,C)*Cross_Prouct(A,B,D)<0&& // 跨立实验;
Cross_Prouct(C,D,A)*Cross_Prouct(C,D,B)<0) // 叉乘异号表示在两侧;
return true;
else return false;
}
@求三角形外心
Point circumcenter(const Point &a, const Point &b, const Point &c) { //返回三角形的外心
Point ret;
double a1 = b.x - a.x, b1 = b.y - a.y, c1 = (a1*a1 + b1*b1) / 2;
double a2 = c.x - a.x, b2 = c.y - a.y, c2 = (a2*a2 + b2*b2) / 2;
double d = a1*b2 - a2*b1;
ret.x = a.x + (c1*b2 - c2*b1) / d;
ret.y = a.y + (a1*c2 - a2*c1) / d;
return ret;
}
@极角排序
double cross(point p1, point p2, point q1, point q2) { // 叉积计算
return (q2.y - q1.y)*(p2.x - p1.x) - (q2.x - q1.x)*(p2.y - p1.y);
}
bool cmp(point a, point b) {
point o;
o.x = o.y = 0;
return cross(o, b, o, a) < 0; // 叉积判断
}
sort(convex + 1, convex + cnt, cmp); // 按角排序, 从小到大
学如逆水行舟,不进则退