# 1. 三角魔法

## 描述

• −109<=x,y<=109
• 点在边上也属于三角形内

## 示例

输入: triangle = [[0,0],[2,0],[1,2]] point= [1,1]



## 代码

class Vector2d
{
public:
double x_;
double y_;

public:
Vector2d(double x, double y) : x_(x), y_(y) {}
Vector2d() : x_(0), y_(0) {}

//二维向量叉乘, 叉乘的结果其实是向量，方向垂直于两个向量组成的平面，这里我们只需要其大小和方向
double CrossProduct(const Vector2d vec)
{
return x_ * vec.y_ - y_ * vec.x_;
}

//二维向量点积
double DotProduct(const Vector2d vec)
{
return x_ * vec.x_ + y_ * vec.y_;
}

//二维向量减法
Vector2d Minus(const Vector2d vec) const
{
return Vector2d(x_ - vec.x_, y_ - vec.y_);
}

//判断点M,N是否在直线AB的同一侧
static bool IsPointAtSameSideOfLine(const Vector2d &pointM, const Vector2d &pointN,
const Vector2d &pointA, const Vector2d &pointB)
{
Vector2d AB = pointB.Minus(pointA);
Vector2d AM = pointM.Minus(pointA);
Vector2d AN = pointN.Minus(pointA);

//等于0时表示某个点在直线上
return AB.CrossProduct(AM) * AB.CrossProduct(AN) >= 0;
}
};

//三角形类
class Triangle
{
private:
Vector2d pointA_, pointB_, pointC_;

public:
Triangle(Vector2d point1, Vector2d point2, Vector2d point3)
: pointA_(point1), pointB_(point2), pointC_(point3)
{
//todo 判断三点是否共线
}

//计算三角形面积
double ComputeTriangleArea()
{
//依据两个向量的叉乘来计算，可参考http://blog.csdn.net/zxj1988/article/details/6260576
Vector2d AB = pointB_.Minus(pointA_);
Vector2d BC = pointC_.Minus(pointB_);
return fabs(AB.CrossProduct(BC) / 2.0);
}

bool IsPointInTriangle1(const Vector2d pointP)
{
double area_ABC = ComputeTriangleArea();
double area_PAB = Triangle(pointP, pointA_, pointB_).ComputeTriangleArea();
double area_PAC = Triangle(pointP, pointA_, pointC_).ComputeTriangleArea();
double area_PBC = Triangle(pointP, pointB_, pointC_).ComputeTriangleArea();

if (fabs(area_PAB + area_PBC + area_PAC - area_ABC) < 0.000001)
return true;
else
return false;
}

bool IsPointInTriangle2(const Vector2d pointP)
{
return Vector2d::IsPointAtSameSideOfLine(pointP, pointA_, pointB_, pointC_) &&
Vector2d::IsPointAtSameSideOfLine(pointP, pointB_, pointA_, pointC_) &&
Vector2d::IsPointAtSameSideOfLine(pointP, pointC_, pointA_, pointB_);
}

bool IsPointInTriangle3(const Vector2d pointP)
{
Vector2d AB = pointB_.Minus(pointA_);
Vector2d AC = pointC_.Minus(pointA_);
Vector2d AP = pointP.Minus(pointA_);
double dot_ac_ac = AC.DotProduct(AC);
double dot_ac_ab = AC.DotProduct(AB);
double dot_ac_ap = AC.DotProduct(AP);
double dot_ab_ab = AB.DotProduct(AB);
double dot_ab_ap = AB.DotProduct(AP);

double tmp = 1.0 / (dot_ac_ac * dot_ab_ab - dot_ac_ab * dot_ac_ab);

double u = (dot_ab_ab * dot_ac_ap - dot_ac_ab * dot_ab_ap) * tmp;
if (u < 0 || u > 1)
return false;
double v = (dot_ac_ac * dot_ab_ap - dot_ac_ab * dot_ac_ap) * tmp;
if (v < 0 || v > 1)
return false;

return u + v <= 1;
}

bool IsPointInTriangle4(const Vector2d pointP)
{
Vector2d PA = pointA_.Minus(pointP);
Vector2d PB = pointB_.Minus(pointP);
Vector2d PC = pointC_.Minus(pointP);
double t1 = PA.CrossProduct(PB);
double t2 = PB.CrossProduct(PC);
double t3 = PC.CrossProduct(PA);
return t1 * t2 >= 0 && t1 * t3 >= 0;
}
};

class Solution
{
public:
/**
* @param triangle: Coordinates of three points
* @param point: Xiaoqi's coordinates
* @return: Judge whether you can cast magic
*/
string castMagic(vector<vector<int>> &triangle, vector<int> &point)
{
Triangle tri(Vector2d(triangle[0][0], triangle[0][1]),
Vector2d(triangle[1][0], triangle[1][1]),
Vector2d(triangle[2][0], triangle[2][1]));
return tri.IsPointInTriangle3(Vector2d(point[0], point[1])) ? "Yes" : "No";
}
};


# 2. 区间异或

## 描述

• 4<=len(num)<=50000
• 0<=num[i]<=100000000
• num中视作下标从1开始，而不是0
• 左右区间可能重合

## 示例

输入: num = [1,2,3,4,5] ask = [[1,2,3,4],[1,2,4,5]]



## 代码

typedef long long ll;
#define N 100010
ll maxx[N][20];
ll minn[N][20];
void RMQ(ll n)
{
for (ll j = 1; j < 20; j++)
for (ll i = 1; i <= n; i++)
if (i + (1 << j) - 1 <= n)
{
maxx[i][j] = max(maxx[i][j - 1], maxx[i + (1 << (j - 1))][j - 1]);
minn[i][j] = min(minn[i][j - 1], minn[i + (1 << (j - 1))][j - 1]);
}
}
ll get_max(ll a, ll b)
{
ll k = (ll)(log(b - a + 1.0) / log(2.0));
return max(maxx[a][k], maxx[b - (1 << k) + 1][k]);
}
ll get_min(ll a, ll b)
{
ll k = (ll)(log(b - a + 1.0) / log(2.0));
return min(minn[a][k], minn[b - (1 << k) + 1][k]);
}
class Solution
{
public:
/**
* @param num: array of num
* @return: return the sum of xor
*/
{
for (ll i = 0; i < num.size(); i++)
{
minn[i + 1][0] = maxx[i + 1][0] = num[i];
}
ll n = num.size();
RMQ(n);
ll ans = 0;
{
ll l1 = as[0], r1 = as[1];
ll l2 = as[2], r2 = as[3];
ll tmp = get_max(l1, r1) + get_min(l2, r2);
ans ^= tmp;
}
return ans;
}
};


# 3. 五子回文

## 描述

• s.length<=106
• 字符串s只包含小写字母

## 示例

输入：s = "abcba"



输入：s = "abcbabcccb"



## 代码

class Solution
{
public:
/**
* @param s: The given string
* @return: return the number of Five-character palindrome
*/
int pd(string &s, int mid)
{
bool f1 = s[mid - 1] == s[mid + 1];
bool f2 = s[mid - 2] == s[mid + 2];
bool f3 = (s[mid - 1] != s[mid - 2]) & (s[mid] != s[mid - 2]) & (s[mid] != s[mid - 1]);
return f1 & f2 & f3;
}
int Fivecharacterpalindrome(string &s)
{
int n = s.size();
if (n < 5)
return 0;
int ans = 0;
for (int i = 2; i < n - 2;)
{
if (pd(s, i))
{
i += 2;
ans++;
}
else
{
i++;
}
}
return ans;
}
};


# 4. 小栖的金字塔

## 描述

• 1<=k<=n<=107
• 由于方案数很大，请对方案数取模1e9+7

## 示例

输入：n=3,k=[1,2,3]



## 代码

typedef long long LL;
const LL mod = 1e9 + 7;
const LL maxn = 1e7 + 10;
LL num[maxn];
LL inverse(LL x, LL y) ///快速幂加费马小定理求逆元
{
LL sum = 1;
while (y)
{
if (y & 1)
sum = sum * x % mod;
y /= 2;
x = x * x % mod;
}
return sum % mod;
}
class Solution
{
public:
/**
* @param n: The number of pyramid levels n
* @param k: Possible coordinates k
* @return: Find the sum of the number of plans
*/
int pyramid(int n, vector<int> &k)
{
num[1] = num[0] = 1;
for (int i = 2; i <= n; i++)
{
num[i] = ((6 * i - 3) * num[i - 1] % mod - (i - 2) * num[i - 2] % mod + mod) % mod * inverse(i + 1, mod - 2) % mod;
}
LL ans = 0;
for (auto x : k)
{
x = n - x + 1;
LL tmp = x == 1 ? 1 : num[x - 1] * 2 % mod;
ans = (ans + tmp) % mod;
}
return int(ans);
}
};

• 点赞 4
• 评论
• 分享
x

海报分享

扫一扫，分享海报

• 收藏
• 手机看

分享到微信朋友圈

x

扫一扫，手机阅读

• 打赏

打赏

riba2534

你的鼓励将是我创作的最大动力

C币 余额
2C币 4C币 6C币 10C币 20C币 50C币
• 一键三连

点赞Mark关注该博主, 随时了解TA的最新博文