On a circle lie 2 n 2n 2n distinct points, with the following property: however you choose 3 3 3 chords that connect 3 3 3 disjoint pairs of points, no point strictly inside the circle belongs to all 3 3 3 chords. The points are numbered 1 , 2 , … , 2 n 1, \, 2, \, \dots, \, 2n 1,2,…,2n in clockwise order.
Initially, k k k chords connect k k k pairs of points, in such a way that all the 2 k 2k 2k endpoints of these chords are distinct.
You want to draw n − k n - k n−k additional chords that connect the remaining 2 ( n − k ) 2(n - k) 2(n−k) points (each point must be an endpoint of exactly one chord).
In the end, let x x x be the total number of intersections among all n n n chords. Compute the maximum value that x x x can attain if you choose the n − k n - k n−k chords optimally.
Note that the exact position of the 2 n 2n 2n points is not relevant, as long as the property stated in the first paragraph holds.
The first line contains a single integer t t t ( 1 ≤ t ≤ 100 1 \le t \le 100 1≤t≤100) — the number of test cases. Then t t t test cases follow.
The first line of each test case contains two integers n n n and k k k ( 1 ≤ n ≤ 100 1 \le n \le 100 1≤n≤100, 0 ≤ k ≤ n 0 \le k \le n 0≤k≤n) — half the number of points and the number of chords initially drawn.
Then k k k lines follow. The i i i-th of them contains two integers x i x_i xi and y i y_i yi ( 1 ≤ x i , y i ≤ 2 n 1 \le x_i, \, y_i \le 2n 1≤xi,yi≤2n, x i ≠ y i x_i \ne y_i xi=yi) — the endpoints of the i i i-th chord. It is guaranteed that the 2 k 2k 2k numbers x 1 , y 1 , x 2 , y 2 , … , x k , y k x_1, \, y_1, \, x_2, \, y_2, \, \dots, \, x_k, \, y_k x1,y1,x2,y2,…,xk,yk are all distinct.
For each test case, output the maximum number of intersections that can be obtained by drawing n − k n - k n−k additional chords.
4
4 2
8 2
1 5
1 1
2 1
2 0
10 6
14 6
2 20
9 10
13 18
15 12
11 7
4
0
1
14
In the first test case, there are three ways to draw the 2 2 2 additional chords, shown below (black chords are the ones initially drawn, while red chords are the new ones):
We see that the third way gives the maximum number of intersections, namely 4 4 4.
In the second test case, there are no more chords to draw. Of course, with only one chord present there are no intersections.
In the third test case, we can make at most one intersection by drawing chords 1 − 3 1-3 1−3 and 2 − 4 2-4 2−4, as shown below:
在一个圆上有 2 n 2n 2n 个不同的点,这些点具有以下性质:无论你如何选择连接 3 3 3 对不相交点的 3 3 3 条弦,严格意义上,圆内没有点属于所有 3 3 3 条弦。这些点按顺时针顺序编号为 1 , 2 , … , 2 n 1, \, 2, \, \dots, \, 2n 1,2,…,2n 。
最初, k k k 条弦连接 k k k 对点,使得这些弦的所有 2 k 2k 2k 端点都是不同的。
您希望绘制连接其余 2 ( n − k ) 2(n - k) 2(n−k) 个点的 n − k n - k n−k 条额外的弦(每个点必须是一条弦的端点)。
最后,假设 x x x 是所有 n n n 条弦的交点总数。计算如果最优化地选择 n − k n - k n−k 条弦, x x x 所能达到的最大值。
注意,只要第一段所述的性质成立, 2 n 2n 2n 点的具体位置并不重要。
第一行包含一个整数 t t t ( 1 ≤ t ≤ 100 1 \le t \le 100 1≤t≤100 ) - 测试用例的数量。然后是 t t t 个测试用例。
每个测试用例的第一行包含两个整数 n n n 和 k k k ( 1 ≤ n ≤ 100 1 \le n \le 100 1≤n≤100 , 0 ≤ k ≤ n 0 \le k \le n 0≤k≤n )–最初绘制的点数和和弦数的一半。
然后是 k k k 行。其中的 i i i /th包含两个整数 x i x_i xi 和 y i y_i yi ( 1 ≤ x i , y i ≤ 2 n 1 \le x_i, \, y_i \le 2n 1≤xi,yi≤2n , x i ≠ y i x_i \ne y_i xi=yi )-- i i i /th弦的端点。可以保证 2 k 2k 2k 个数字 x 1 , y 1 , x 2 , y 2 , … , x k , y k x_1, \, y_1, \, x_2, \, y_2, \, \dots, \, x_k, \, y_k x1,y1,x2,y2,…,xk,yk 都是不同的。
对于每个测试用例,输出绘制 n − k n - k n−k 条额外弦线所能获得的最大交叉点数量。
在第一个测试案例中,有三种绘制 2 2 2 附加和弦的方法,如下图所示(黑色和弦为最初绘制的和弦,红色和弦为新绘制的和弦):
我们可以看到,第三种方法得到的交点数最多,即 4 4 4 。
在第二个测试案例中,没有更多的弦需要绘制。当然,如果只有一条弦,就没有交点。
在第三种测试情况中,我们最多可以通过绘制弦 1 − 3 1-3 1−3 和 2 − 4 2-4 2−4 来得到一个交点,如下图所示:
以上来自 以上来自 以上来自CodeForces ,翻译: D e e p L ,翻译:DeepL ,翻译:DeepL
构造好后,判断交点即可。
#include
using namespace std;
#define int long long
int n, k;
int ans;
inline bool check_and_done(pair<int, int> x, pair<int, int> y);
inline void solve();
inline void work() {
int T;
cin >> T;
while (T--)solve();
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
work();
}
inline bool check_and_done(pair<int, int> x, pair<int, int> y) {
if (x.first > y.first)swap(x, y);
return x.second > y.first && x.second < y.second;
}
inline void solve() {
cin >> n >> k;
vector<pair<int, int> > storage_member;
vector<bool> vis(2 * n + 1);
for (int i = 1, x, y; i <= k; i++) {
cin >> x >> y;
if (x > y)swap(x, y);
storage_member.push_back(make_pair(x, y));
vis[x] = vis[y] = 1;
}
vector<int> unvis_member_temp;
for (int i = 1; i <= 2 * n; i++)if (!vis[i])unvis_member_temp.push_back(i);
for (int i = 0; i < n - k; i++)storage_member.push_back(make_pair(unvis_member_temp[i], unvis_member_temp[i + n - k]));
ans = 0;
for (int i = 0; i < n; i++)for (int j = i + 1; j < n; j++)if (check_and_done(storage_member[i], storage_member[j]))ans += 1;
cout << ans << endl;
}
此题洛谷评分: 普及 + / 提高 \textcolor{green}{ 普及+/提高} 普及+/提高,是不是非常简单?
还在为 C o d e F o r c e s CodeForces CodeForces,全英文而苦恼吗?还在为洛谷的()()翻译而苦恼吗?翻译插件这不就来了吗。