ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

C. Maximize the Intersections

2021-07-26 11:33:09  阅读:360  来源: 互联网

标签:typedef Intersections 个点 int long Maximize 2n include


C. Maximize the Intersections

[link](Problem - C - Codeforces)

题意

在一个圆上有2n个不同的点,具有以下性质:无论你如何选择3条连接3个互不相干的点的弦,在圆内没有一个点严格属于所有3条弦。这些点按顺时针顺序被编号为1,2,…,2n。

最初,k条和弦连接了k对点,其方式是这些和弦的所有2k个端点是不同的。

你想画出n-k条额外的和弦,连接剩余的2(n-k)个点(每个点必须正好是一个和弦的端点)。

最后,让x成为所有n条弦的交叉点的总数。计算如果你以最佳方式选择n-k条弦,x能达到的最大值。

请注意,2n个点的确切位置并不重要,只要第一段中所述的属性成立即可。

题解

首先对于两条弦是否相交如何判断?

假设x1 < y1, x2 < y2且x1 < x2则当且仅当 x2 < y1 && y1 < y2时两弦有交点

什么情况下交点数最多?

假设有2n个点,从 1 - n + 1连一条边,这个弦的两侧的点数相同,弦的左右的点两两配对,则其余点对于该弦的贡献就是n - 1,因此,我们将所有的点按照 i - i + n 这种形式排列好,那么每一条弦的贡献一定都是n - 1,因为一共2n个点,n个弦,每个弦最多贡献是n - 1所以这种情况一定是最优的,因此,把剩下的没连过的点按照相对顺序依照这种方法连接即可。然后暴力跑一遍一否成立即可。

Code

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <set>
#include <queue>
#include <vector>
#include <map>
#include <unordered_map>
#include <cmath> 
#include <stack>
#include <iomanip> 
#define x first
#define y second
#define eps 1e-7
using namespace std;
typedef long double ld;
typedef long long LL;
typedef pair<int, int> PII;
typedef unsigned long long ULL;
const int N = 5e4 + 10, M = 30010, INF = 0x3f3f3f3f, P = 131, mod = 1e9 + 7;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int n, m;

bool check(PII c, PII d) { // 判断是否有交点 
	if (c.x > d.x) swap(c, d); // c靠前 
	return c.y < d.y &&  d.x < c.y;
}
int main () {
	cin.tie(nullptr)->sync_with_stdio(false);
	int T;
	cin >> T;
	while (T --) {
			cin >> n >> m; // n条弦和用了m条 
			vector<PII> chords; // 存所有弦的xi,yi 
			vector<bool> used(2 * n + 1, false); // 判断哪些弦题目中给了 
			for (int i = 1; i <= m; i ++ ) {
				int x, y;
				cin >> x >> y;
				if (x > y) swap(x, y); // 从小到大 定序 方便后面操作 
				chords.push_back({x, y});  // 将弦加入 
				used[x] = used[y] = true; // 表示用过了 
			}
			vector<int> unused; // 存没用过的弦 
			for (int i = 1; i <= 2 * n; i ++ )
				if (!used[i]) unused.push_back(i); // 找到所有没用过的弦 
			for (int i = 0; i < n - m; i ++ )  // 将所有没用过的弦按照相对顺序,依照最优策略连弦 
				chords.push_back({unused[i], unused[i + n - m]}); // 加入到方案内 
			int res = 0;
			for (int i = 0; i < n; i ++ )  // 暴力枚举 
				for (int j = i + 1; j < n; j ++ )
					res += check(chords[i], chords[j]); // 是否合理 
			cout << res << endl;
		}
	 return 0;
}



标签:typedef,Intersections,个点,int,long,Maximize,2n,include
来源: https://blog.csdn.net/a12377978/article/details/119105605

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有