前言

在我的代码中

  • 不会给出完整的代码,仅给出部分核心代码
  • long是64位整数
  • endl已经被模板特化,性能和\n相当

B 冰冰的电子邮箱

这题看到判断邮箱是否合法,很明显这就是一道正则表达式匹配匹配题,直接用正则表达式判断合不合法即可。

@之前

  • 要求是由字母和数字组成
  • 除了开头和结尾的位置可以出现'.'
  • 串长在 [1, 64]

前面两个,我们可以写出正则(第一个字符一定是字母或者数字。随后可能是任意的字母,数字,点进行排列组合,紧接着一定是字母或者数字。也可能是什么都没有)

[A-Za-z0-9]([A-Za-z0-9.]*[A-Za-z0-9])?

紧接着,限制了串长是[1, 64],所以加上限制,变成

(?=.{1,64}@)([A-Za-z0-9]([A-Za-z0-9.]*[A-Za-z0-9])?)

@之后

  • 要求是由字母和数字组成
  • 除了开头和结尾的位置可以出现'.'或者'-'
  • 串长在 [1, 255]

和上面的一样,只要在'.'出现的地方加上可能会出现'-'就完啦,最后加上长度限制即可

(?=.{1,255}$)([A-Za-z0-9]([A-Za-z0-9.-]*[A-Za-z0-9])?)

最后

直接拼接合并就好了,记得是从头匹配到尾,所以要记得加^$

^(?=.{1,64}@)([A-Za-z0-9]([A-Za-z0-9.]*[A-Za-z0-9])?)@(?=.{1,255}$)([A-Za-z0-9]([A-Za-z0-9.-]*[A-Za-z0-9])?)$

代码

const std::regex email_pattern(
        R"(^(?=.{1,64}@)([A-Za-z0-9]([A-Za-z0-9.]*[A-Za-z0-9])?)@(?=.{1,255}$)([A-Za-z0-9]([A-Za-z0-9.-]*[A-Za-z0-9])?)$)"
);
void solve() {
    std::string email;
    std::cin >> email;
    std::cout << (std::regex_match(email, email_pattern) ? "Yes" : "No") << std::endl;
}
#define T_CASE

冰冰的分界线

这题大家都很容易想到说用直线方程来判断,但是用点斜式来进行判断是否是同一直线,存在很多问题。比如说要考虑斜率是否存在,浮点数的精度问题等等。

在这里,我的思路大体上和大家是一样的,但是我们采用直线的一般方程,通过一般方程(化简后)是否相等来判断共线。

大体代码如下(不懂的话看看数学课本,推一下公式吧)

template <typename T> // 二维平面 点
using point2d_t = std::pair<T, T>;
template <typename T> // 二维平面 直线一般式
using general_line2d_t = std::tuple<T, T, T>;

namespace lines {
template <typename T> // 出两个二维点 求线段垂直平分线的一般方程
general_line2d_t<T> verticle_bisector(const point2d_t<T> &p1,
                                      const point2d_t<T> &p2) {
    const auto &[x1, y1] = p1;
    const auto &[x2, y2] = p2;
    auto a = (x1 - x2) * 2;
    auto b = (y1 - y2) * 2;
    auto c = -(x1 * x1 - x2 * x2 + y1 * y1 - y2 * y2);
    return {a, b, c};
}
template <typename T> // 将一般方程化到最简
general_line2d_t<T> reduce(const general_line2d_t<T> &l) {
    auto [a, b, c] = l;
    auto gcd = std::gcd(std::gcd(a, b), c);
    a /= gcd, b /= gcd, c /= gcd;
    if (a < 0)
        a = -a, b = -b, c = -c;
    if (a == 0 and b < 0)
        b = -b, c = -c;
    return {a, b, c};
}
}; // namespace lines

void solve() {
    long n;
    std::cin >> n;
    std::vector<long> xi(n), yi(n);
    for (auto &&x : xi)
        std::cin >> x;
    for (auto &&y : yi)
        std::cin >> y;
    std::set<general_line2d_t<long>> lines;
    for (int i = 0; i < n; ++i)
        for (int j = i + 1; j < n; ++j) {
            auto line = lines::reduce(
                lines::verticle_bisector<long>({xi[i], yi[i]}, {xi[j], yi[j]}));
            lines.emplace(line);
        }
    std::cout << lines.size() << std::endl;
}
#define T_CASE