您的位置:首页 > 其它

foj 1973 How many stars

2010-10-24 20:18 246 查看
//一个巨恶心的几何题目.....

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAXN 1001
#define INF 1000001
struct Point {
__int64 x, y;
double val;
int id;
bool operator<(const Point& p) const {
return val < p.val;
}
}point[MAXN], cp[MAXN];
int A[MAXN][MAXN], B[MAXN][MAXN];
inline void swap(Point& p1, Point& p2) {
Point tmp = p1;
p1 = p2;
p2 = tmp;
}
//通过矢量叉积求极角关系(p0p1)(p0p2)
//d > 0 ,p0p1在p0p2顺时针方向上
inline __int64 multi(Point p0, Point p1, Point p2)
{
return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}

inline int mod(int x, int n)
{
return ((x % n) + n) % n;
}

//二分求在直线一边的点数
int getNum(int j, int n) {
int l = mod(j+1, n-1);
int r = mod(j-1, n-1);
if(multi(point[n-1], point[r], point[j]) < 0)
return mod(r-j, n-1);
if(multi(point[n-1], point[l], point[j]) > 0)
return 0;
while(mod(l+1, n-1) != r)
{
int mid = mod(l + (mod(r-l, n-1) >> 1), n-1);
if(multi(point[n-1], point[mid], point[j]) > 0)
r = mid;
else
l = mid;
}
return mod(l-j, n-1);
}

int main() {
//freopen("in.txt", "r", stdin);
int t, n, m, id = 1;
scanf("%d", &t);
int i, j;
while(t--) {
scanf("%d", &n);
int a, b, c;
for(i=0; i<n; i++) {
scanf("%d%d", &a, &b);
cp[i].x = a;
cp[i].y = b;
cp[i].id = i;
}
for(i=0; i<n; i++) {
for(j=0; j<n; j++) {
point[j] = cp[j];
if(i == j) {
continue;
}
point[j].val = atan2((double)(point[j].y - cp[i].y), (double)(point[j].x - cp[i].x));
}
swap(point[n-1], point[i]);
sort(point, point + (n-1));
for(j=0; j<n-1; j++) {
A[i][point[j].id] = j;
B[i][point[j].id] = getNum(j, n);
}
}
scanf("%d", &m);
int tmp[6], ans;
Point tra[3];
printf("Case %d:/n", id++);
while(m--) {
ans = 0;
scanf("%d%d%d", &a, &b, &c);

tra[0] = cp[a];
tra[1] = cp[b];
tra[2] = cp[c];

//确定三角形为逆时针方向
int maxx = INF, maxy = INF, tmpId = -1;
for(i=0; i<3; i++) {
if(tra[i].x < maxx || (tra[i].x == maxx && tra[i].y < maxy)) {
tmpId = i;
maxx = tra[i].x;
maxy = tra[i].y;
}
}

//tra[0]为最左下的点
swap(tra[0], tra[tmpId]);
for(i=1; i<3; i++) {
tra[i].val = atan2((double)(tra[i].y - tra[0].y), (double)(tra[i].x - tra[0].x));
}
sort(tra+1, tra+3);

tmp[0] = mod(A[tra[0].id][tra[2].id] - A[tra[0].id][tra[1].id], n-1) - 1;
tmp[1] = mod(A[tra[1].id][tra[0].id] - A[tra[1].id][tra[2].id], n-1) - 1;
tmp[2] = mod(A[tra[2].id][tra[1].id] - A[tra[2].id][tra[0].id], n-1) - 1;

tmp[3] = n - 2 - B[tra[0].id][tra[1].id];
tmp[4] = n - 2 - B[tra[1].id][tra[2].id];
tmp[5] = n - 2 - B[tra[2].id][tra[0].id];

for(i=0; i<6; i++) {
ans += tmp[i];
}
ans -= 2 * (n - 3);
printf("%d/n", ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: