UVA 12123 - Magnetic Train Tracks(计数问题)

题目链接:12123 - Magnetic Train Tracks

题意:给定n个点,求有几个锐角三角形。

思路:和UVA 11529是同类的题,枚举一个做原点,然后剩下点根据这个原点进行极角排序,然后利用two pointer去遍历一遍,找出角度小于90度的锐角,然后扣掉这些得到钝角三角形的个数,然后在用总情况去扣掉钝角就是锐角或直角

代码:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;

const double eps = 1e-9;
const double pi = acos(-1.0);
const int N = 1205;
int n;
struct Point {
	double x, y;
	void read() {
		scanf("%lf%lf", &x, &y);
 	}
} p[N];

double r[N * 2];
int C(int n, int m) {
	if (n < m) return 0;
	int ans = 1;
	for (int i = 0; i < m; i++)
		ans = ans * (n - i) / (i + 1);
	return ans;
}

double cal(Point a, Point b) {
	return atan2(b.y - a.y, b.x - a.x);
}

int solve(int num) {
	int tn = 0;
	for (int i = 0; i < n; i++) {
		if (i == num) continue;
		r[tn++] = cal(p[num], p[i]);
 	}
 	sort(r, r + tn);
 	for (int i = 0; i < tn; i++)
 		r[tn + i] = r[i] + 2 * pi;
	int j = 1;
	int ans = 0;
	for (int i = 0; i < tn; i++) {
		while (fabs(r[j] - r[i]) - pi / 2 <= -eps) j++;
		ans += j - i - 1;
 	}
 	return C(tn, 2) - ans;
}

int main() {
	int cas = 0;
	while (~scanf("%d", &n) && n) {
		for (int i = 0; i < n; i++)
			p[i].read();
		int ans = 0;
		for (int i = 0; i < n; i++)
			ans += solve(i);
		printf("Scenario %d:\n", ++cas);
		printf("There are %d sites for making valid tracks\n", C(n, 3) - ans);
 	}
	return 0;
}

UVA 12123 - Magnetic Train Tracks(计数问题),布布扣,bubuko.com

时间: 2024-12-17 14:43:06

UVA 12123 - Magnetic Train Tracks(计数问题)的相关文章

UVA - 12123 Magnetic Train Tracks

Description The rail roads of Japan are being redesigned. So the governent is planning to install ultra-modern Magnetic trains instead of the current normal trains. As fuel price have gone high and nations have shut down their nuclear plants so the p

LA 4064 Magnetic Train Tracks

题意:给定平面上$n(3\leq n \leq 1200)$个无三点共线的点,问这些点组成了多少个锐角三角形. 分析:显然任意三点可构成三角形,而锐角三角形不如直角或钝角三角形容易计数,因为后者有且仅有一个角度大于等于$90^{\circ}$的特征角. 于是考虑固定平面上每一个顶点,也就是固定了钝角或直角三角形的一个特征顶点,将其余所有点按照极角排序,然后固定一条侧边,统计有多少条 边和该侧边夹角不小于$90^{\circ}$.这些边必然是连续的,可以使用区间统计的办法,用二分查找在$O(log

LA 4064 (计数 极角排序) Magnetic Train Tracks

这个题和UVa11529很相似. 枚举一个中心点,然后按极角排序,统计以这个点为钝角的三角形的个数,然后用C(n, 3)减去就是答案. 另外遇到直角三角形的情况很是蛋疼,可以用一个eps,不嫌麻烦的话就用整数的向量做点积. 1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 using namespace std; 5 6 typedef long long LL; 7 const int ma

UVaLive 4064 Magnetic Train Tracks (极角排序)

题意:给定 n 个不三点共线的点,然后问你能组成多少锐角或者直角三角形. 析:可以反过来求,求有多少个钝角三角形,然后再用总的减去,直接求肯定会超时,但是可以枚举每个点,以该点为钝角的那个顶点,然后再枚举另一条边,维护与该边大于90度并小于等于180度的点的数量,这里要用极角排序,这样就可以减小时间复杂度,但是会WA,要控制精度,但是精度是个迷,表示不会. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #in

UVA 1362 - Exploring Pyramids(计数问题+区间DP)

题目链接:1362 - Exploring Pyramids 白书上的例题,思路是对于每个结点,往后遍历分为左右两边子树来考虑,左边的子树为去掉根节点剩下的子树,而右边是要算上根节点的,这样就不会有重复的情况出现,然后根据乘法原理,左右两边情况相乘为总情况数,然后计算这些总和. f[i][j]表示[i,j]结点的情况种数,那么 f[i][j] = sum{f[i + 1][k - 1] * f[k][j]},并且s[i] == s[k] == s[j],因为i, j, k表示的是根节点必须相同.

UVA 11538 - Chess Queen(数论+计数问题)

题目链接:11538 - Chess Queen 题意:给一个n*m棋盘,问放两个皇后,使得两个皇后互相能攻击到,有几种放法 思路:分横竖,对角线来考虑. 横:n * A(m, 2)种 竖:m * A(n, 2)种 对角线:由于有两条,可以算一条再乘2 2 * 所有对角线和(A(对角线格数,2)). 那么对角线格数为:(1, 2, 3, 4 ... n .n .n .n.n - 1. .. 4. 3 .2. 1) 然后为n的有m - n + 1条(m >= n) 所以答案为:2*(2*∑i*(i

UVa 11586 - Train Tracks

题目:给你一些积木碎片,每个碎片的两端只能是凸或凹(M或F),凸凹可拼起来,能否拼成一个环. 分析:图论,欧拉回路.判断入度等于出度即可,即M和F相同且大于1组. 说明:╮(╯▽╰)╭. #include <cstring> #include <cstdio> char buf[202]; int main() { int n; while (~scanf("%d",&n)) { getchar(); while (n --) { gets(buf);

uva 11529 - Strange Tax Calculation(计数问题)

题目链接:uva 11529 - Strange Tax Calculation 题目大意:给出若干个点,保证随意三点不共线.随意选三个点作为三角行,其它点若又在该三角形内,则算是该三角形内部的点.问全部情况的三角形平均每一个三角形有多少个内部点. 解题思路:三角形的总数非常easy求C(3n),如今就是要求各个三角形内部点的总数.相同我们能够反过来,求每一个点在多少个三角形的内部. 然后我们确定一个点,求该点在多少个三角的内部.剩余n-1个点.能够组成C(3n?1])个三角形,所以仅仅要求出该

《算法竞赛入门经典——训练指南》第二章题库

UVa特别题库 UVa网站专门为本书设立的分类题库配合,方便读者提交: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=442 注意,下面注有"extra"的习题并没有在书中出现,但在上面的特别题库中有,属于附加习题. 基础练习 (Basic Problems) UVa11388 GCD LCM UVa11889 Benefit UVa10943 How do y