数学结论、计算几何

排列组合

圆排列

有限多重集的排列 n!/(n1!*n2!*...*nk!)

n元无限集可重-r组合C(n+r-1,r)种。

n元无限集取r个,n中每个至少出现一次C(r-1,n-1)(r≥n)



直线分平面:

f(1) = 2

f(n) = f(n-1)+n = n(n+1)/2+1

折线分平面:

f(1) = 2

f(n) = f(n-1)+4(n-1)+1 = 2n^2-n+1

圆分平面:

f(1) = 2

f(n) = f(n-1)+2(n-1) = n^2-n+2

三角形分平面:

f(1) = 2

f(n) = f(n-1)+6*(n-1)

平面分空间:

f(1) = 2

g(n) = n(n+1)/2+1

f(n) = f(n-1)+g(n-1) = (n^3+5n)/6+1



已知p1(x1,x1),p2(x2,y2),求Ax+By+C = 0

A = y2 - y1

B = x1 - x2

C = x2*y1-x1*y2


海伦公式

, p为半周长


四边形最大面积


斯特林公式:

n很大时,


笛卡尔定理

4个圆相切,外切k = 1/r,内切k = -1/r,圆退化成直线k = 0。


一个长度为n-2的Purfer序列唯一对应一个n个点的树,且Purfer序列中i出现的次数就是节点i的度数减一。


全面积为πa2的圆锥最大面积为sqrt(2)/12*πa^3。


正弦定理sinA / a = sinB / b = sinC/c

余弦定理a2 = b2 + c2- 2bc·cosA

正切定理(a+b)/(a-b) = tan[(A+B)/2]/tan[(A-B)/2]


多边形面积  

如果逆时针给出点坐标,值为正,

如果顺时针给出点坐标,值为负。



Bash游戏:

有一堆石子共有N个。A B两个人轮流拿,A先拿。每次最少拿1颗,最多拿K颗,拿到最后1颗石子的人获胜。

若n不足k+1,则A第一次取完,A胜。

若n是k+1的倍数,每次A取x,B都能取k+1-x,B胜。

否则,A胜。



威佐夫游戏:

有2堆石子。A B两个人轮流拿,A先拿。每次可以从一堆中取任意个或从2堆中取相同数量的石子,但不可不取。

两堆石头x < y,若(y-x)*(sqrt(5)+1) / 2+1) == x,则B胜。否则A胜。



1/a循环节长度:

a先约去2和5的因子->b,然后球欧拉函数值?,求一个最小的x,使得x|?且10^x%b == 1。



struct node
{
    int x,y;
    friend bool operator <(node a,node b)
    {
        if(a.x == b.x)  return a.y<b.y;
        return a.x<b.x;
    }
}a[1005],ans[1005];
int n,m,l;

int cross(node a,node b,node c)//向量积
{
    return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
}

int convex(int n)//求凸包上的点
{
    sort(a,a+n);
    int m = 0;
    //求得下凸包,逆时针
    //已知凸包点m个,如果新加入点为i,则向量(m-2,i)必定要在(m-2,m-1)的逆时针方向才符合凸包的性质
    //若不成立,则m-1点不在凸包上。
    for(int i = 0;i < n;i++)
    {
        while(m > 1 && cross(ans[m-1],a[i],ans[m-2])<=0)    m--;
        ans[m++] = a[i];
    }
    int k = m;
    //求得上凸包
    for(int i = n-2;i >= 0;i--)
    {
        while(m > k && cross(ans[m-1],a[i],ans[m-2])<=0)    m--;
        ans[m++] = a[i];
    }
    if(n > 1)   m--;//起始点重复。
    return m;
}

求凸包



double x1,x2,x3,x4,y1,y2,y3,y4;

bool f()
{
    double t1 = (x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
    double t2 = (x2-x1)*(y4-y2)-(x4-x2)*(y2-y1);
    double t3 = (x4-x3)*(y1-y4)-(x1-x4)*(y4-y3);
    double t4 = (x4-x3)*(y2-y4)-(x2-x4)*(y4-y3);
    if(t1*t2 <= 0 && t3*t4 <= 0)    return 1;
    else    return 0;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4);
        if(f()) printf("Yes\n");
        else    printf("No\n");
    }
    return 0;
}

判断线段相交



int x1,x2,x3,x4,y1,y2,y3,y4,z1,z2,z3,z4;

bool f()
{
    int a11 = x1-x2,a12 = x2-x3,a13 = x3-x4;
    int a21 = y1-y2,a22 = y2-y3,a23 = y3-y4;
    int a31 = z1-z2,a32 = z2-z3,a33 = z3-z4;
    if(a11*a22*a33+a12*a23*a31+a13*a21*a32-a13*a22*a31-a11*a23*a32-a12*a21*a33 == 0)    return 1;
    else    return 0;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d%d%d%d%d%d%d%d%d%d",&x1,&y1,&z1,&x2,&y2,&z2,&x3,&y3,&z3,&x4,&y4,&z4);
        if(f()) printf("Yes\n");
        else    printf("No\n");
    }
    return 0;
}

判断四点公面



double XX,YY,R,X1,X2,X3,Y1,Y2,Y3;

bool f()
{
    double a1 = (X1-XX)*(X1-XX)+(Y1-YY)*(Y1-YY);
    double a2 = (X2-XX)*(X2-XX)+(Y2-YY)*(Y2-YY);
    double a3 = (X3-XX)*(X3-XX)+(Y3-YY)*(Y3-YY);
    double rr = R*R;
    if(a1 < rr-1e-6 && a2 < rr-1e-6 && a3 < rr-1e-6)    return 1;
    if(a1 > rr+1e-6 && a2 > rr+1e-6 && a3 > rr+1e-6)
    {
        double t = ((XX-X1)*(X2-X1)+(YY-Y1)*(Y2-Y1))*((XX-X2)*(X1-X2)+(YY-Y2)*(Y1-Y2));
        if(t > 1e-6)
        {
            t = abs((X1-XX)*(Y2-YY)-(X2-XX)*(Y1-YY))/sqrt((X1-X2)*(X1-X2)+(Y1-Y2)*(Y1-Y2));
            if(t*t < rr+1e-6)   return 0;
        }
        t = ((XX-X3)*(X2-X3)+(YY-Y3)*(Y2-Y3))*((XX-X2)*(X3-X2)+(YY-Y2)*(Y3-Y2));
        if(t > 1e-6)
        {
            t = abs((X3-XX)*(Y2-YY)-(X2-XX)*(Y3-YY))/sqrt((X3-X2)*(X3-X2)+(Y3-Y2)*(Y3-Y2));
            if(t*t < rr+1e-6)   return 0;
        }
        t = ((XX-X3)*(X1-X3)+(YY-Y3)*(Y1-Y3))*((XX-X1)*(X3-X1)+(YY-Y1)*(Y3-Y1));
        if(t > 1e-6)
        {
            t = abs((X3-XX)*(Y1-YY)-(X1-XX)*(Y3-YY))/sqrt((X3-X1)*(X3-X1)+(Y3-Y1)*(Y3-Y1));
            if(t*t < rr+1e-6)   return 0;
        }
        return 1;
    }
    return 0;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf",&XX,&YY,&R,&X1,&Y1,&X2,&Y2,&X3,&Y3);
        if(f()) printf("No\n");
        else    printf("Yes\n");
    }
    return 0;
}

判断圆和三角形是否相交


时间: 2024-10-13 15:26:45

数学结论、计算几何的相关文章

hdu4294 Multiple 数学结论 bfs

#include <iostream> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <map> #define inf 0x3f3f3f3f #define ll __in

NOI1999 JZYZOJ1289 棋盘分割 dp 方差的数学结论

http://172.20.6.3/Problem_Show.asp?id=1289 除了下标一坨一坨屎一样挺恶心其他都还挺容易的dp,这道题才发现scanf保留小数位是四舍五入的,惊了. f[k][x1][y1][x2][y2] 嗯写的时候猜错结论了,本来以为是求下属分配方案中平方和与平均数平方*k的差最小的方案赋给f,没想到是直接找最小的. 代码 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream>

Codeforces 577B Modulo Sum:数学 结论【选数之和为m的倍数】

题目链接:http://codeforces.com/problemset/problem/448/C 题意: 给你n个数字,给定m. 问你是否能从中选出若干个数字,使得这些数字之和为m的倍数. 题解: 其实就是要找一些数字,使得之和mod m为0. 开一个vector,存当前已经能够构成的数字之和mod m之后的值. 一开始vector为空,然后枚举n个数字a[i],对于每个数字枚举当前vector中的值v[i],将没有出现过的(a[i]+v[i])%m值加入vector中. 最后判断下vec

BZOJ 1192: [HNOI2006]鬼谷子的钱袋 数学结论

1192: [HNOI2006]鬼谷子的钱袋 Description 鬼谷子非常聪明,正因为这样,他非常繁忙,经常有各诸侯车的特派员前来向他咨询时政.有一天,他在咸阳游历的时候,朋友告诉他在咸阳最大的拍卖行(聚宝商行)将要举行一场拍卖会,其中有一件宝物引起了他极大的兴趣,那就是无字天书.但是,他的行程安排得很满,他他已经买好了去邯郸的长途马车标,不巧的是出发时间是在拍卖会快要结束的时候.于是,他决定事先做好准备,将自己的金币数好并用一个个的小钱袋装好,以便在他现有金币的支付能力下,任何数目的金币

常用数学结论

斯特灵公式是一条用来取n阶乘近似值的数学公式.一般来说,当n很大的时候,n阶乘的计算量十分大,所以斯特灵公式十分好用,而且,即使在 n很小的时候,斯特灵公式的取值已经十分准确. 公式为: 这就是说,对于足够大的整数n,这两个数互为近似值.更加精确地: 或者: 超强大的公式 n!=(2*pi*n)^1/2 *(n/e)^n *e^(a/12*n)

hdu 1018 Big Number 数学结论

Big Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 34084    Accepted Submission(s): 16111 Problem Description In many applications very large integers numbers are required. Some of these

数学、计算几何、位运算常见问题详解

? 矩阵上的问题(3题) Search a 2D Matrix II public int searchMatrix(int[][] matrix, int target) { // write your code here int n = matrix.length; if (n == 0) { return 0; } int m = matrix[0].length; if (m == 0) { return 0; } int i = n - 1; int j = 0; int res =

LightOJ - 1058 - Parallelogram Counting(数学,计算几何)

链接: https://vjudge.net/problem/LightOJ-1058 题意: There are n distinct points in the plane, given by their integer coordinates. Find the number of parallelograms whose vertices lie on these points. In other words, find the number of 4-element subsets o

今天开始认真刷数学

不得不说数学是制胜的法宝,但是也确实很难,系统地针对地进行训练十分有必要: VJUDGE自行训练,发布者lvbu: ID   Title   Begin Time Length Owner 165317    [kuangbin]数学训练一 [Cloned]   5 min later 60 days lvbu 165319    [kuangbin]数学训练三 [Cloned]   5 min later 50.2 days lvbu 165318    [kuangbin]数学训练二 cou