本文分享的必刷题目是从蓝桥云课、洛谷、AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。
欢迎大家订阅我的专栏:算法题解:C++与Python实现!
附上汇总贴:算法竞赛备考冲刺必刷题(C++) | 汇总
【题目来源】
AtCoder:D - Line Crossing
【题目描述】
There are
N
N
N equally spaced points on a circle labeled clockwise as
1
,
2
,
…
,
N
1,2,…,N
1,2,…,N.
圆上有
N
N
N 个等距的点,按顺时针方向依次标记为
1
,
2
,
…
,
N
1, 2, …, N
1,2,…,N。
There are
M
M
M distinct lines, where the
i
i
i-th line passes through two distinct points
A
i
A_i
Ai and
B
i
(
1
≤
i
≤
M
)
B_i (1≤i≤M)
Bi(1≤i≤M).
共有
M
M
M 条不同的直线,其中第
i
i
i 条直线穿过两个不同的点
A
i
A_i
Ai 和
B
i
(
1
≤
i
≤
M
)
B_i (1≤i≤M)
Bi(1≤i≤M)。
Find the number of pairs
(
i
,
j
)
(i,j)
(i,j) satisfying:
求满足以下条件的数对
(
i
,
j
)
(i, j)
(i,j) 的数量:
- 1 ≤ i < j ≤ M 1≤i<j≤M 1≤i<j≤M, and
- the
i
i
i-th and
j
j
j-th lines intersect.
第 i i i 条直线与第 j j j 条直线相交。
【输入】
The input is given from Standard Input in the following format:
N M
A_1 B_1
A_2 B_2
.
.
.
A_M B_M
【输出】
Print the answer.
【输入样例】
8 3
1 5
1 8
2 4
【输出样例】
2
【代码详解】
#include <bits/stdc++.h>
using namespace std;
#define int long long // 定义int为long long类型
int n, m, res1, res2; // n: 模数, m: 点对数, res1/res2: 中间计算结果
int cnt[1000005]; // 计数数组,用于统计每个余数出现的次数
signed main() // 使用signed代替int
{
// 输入模数n和点对数m
cin >> n >> m;
// 处理每个点对
for (int i = 1; i <= m; i++) {
int x, y; // 点对坐标
cin >> x >> y;
x = x - 1, y = y - 1; // 坐标转换为0-based
int t = (x + y) % n; // 计算(x+y) mod n
cnt[t]++; // 统计该余数出现的次数(即平行边的数量)
}
// 计算所有可能的点对组合数C(m,2),即所有线对数量
res1 = m * (m - 1) / 2;
// 计算同余点对的组合数
for (int i = 0; i < n; i++)
if (cnt[i]) // 如果该余数出现过
res2 += cnt[i] * (cnt[i] - 1) / 2; // 计算该余数下点对的组合数,即平行边的数量
// 输出结果:总组合数减去同余组合数
cout << res1 - res2 << endl;
return 0;
}
【运行结果】
8 3
1 5
1 8
2 4
2