zoj数学几何(一)

zoj1010

#include <stdio.h>
#include <math.h>

#define eps 1e-8

double x[1001],y[1001];

double area(int n, double x[], double y[])
{
	int i;
	double ans = 0;
	for(i=1; i<=n; i++)
		ans += x[i]*y[i-1]-y[i]*x[i-1];
	return fabs(ans/2);
}

double cross(int a,int b,int c)
{
	return (x[b]-x[a])*(y[c]-y[a])-(y[b]-y[a])*(x[c]-x[a]);
}

double dot(int a,int b,int c)
{
	return (x[b]-x[a])*(x[c]-x[a])+(y[b]-y[a])*(y[c]-y[a]);
}

int compare(double d)
{
	if(fabs(d)<eps)
		return 0;
	return (d>0)?1:-1;
}

int between(int a, int b, int c)
{
	return compare(dot(a,b,c));
}

int intersect(int s, int t)
{
	int d1 = compare(cross(s,s+1,t));
	int d2 = compare(cross(s,s+1,t+1));
	int d3 = compare(cross(t,t+1,s));
	int d4 = compare(cross(t,t+1,s+1));
	if(d1*d2<0 && d3*d4<0)
		return 1;
	if (d1==0 && between(t,s,s+1)==0   ||
		d2==0 && between(t+1,s,s+1)==0 ||
		d3==0 && between(s,t,t+1)==0   ||
		d4==0 && between(s+1,t,t+1)==0)
		return 2;
	return 0;
}

int main()
{
	int n;
	int i,j;
	int iCase=0;
	while(scanf("%d", &n) && n)
	{
		for(i=1; i<=n; i++)
			scanf("%lf%lf", &x[i], &y[i]);
		x[0]=x[n]; 
		y[0]=y[n];
		if (iCase)	printf("\n");;
		printf("Figure %d: ", ++iCase);
		
		int flag = 1;
		if(n<3)	flag = 0;
			
		for(i=n-3; i>=0 && flag; i--)
			for(j=i+2; j<n  && flag; j++){
				if (i==0 && j==n-1) break;
				if(intersect(i,j))
					flag = 0;
			}
		if (flag)
			printf("%.2lf\n", area(n,x,y));
		else
			printf("Impossible\n");
	}
	return 0;
}

zoj1030

#include <stdio.h>
#include <memory.h>
#include <math.h>

int xNode[200], yNode[200];
int connect[200][10];
char iMask[200][200];
int arrive[200];
int loop[40];
int endNode;
int depth;

double Angle(int x1, int y1, int x2, int y2)
{
	return (atan2((double)(x1*y2 - x2*y1), x1*x2+y1*y2));
}

double area()
{
	int i;
	double s = 0;
	for(i=0; i<depth; i++)
		s += xNode[loop[i+1]]*yNode[loop[i]]-yNode[loop[i+1]]*xNode[loop[i]];
	return s/2;
}

int isInside(int i, int k) {
	int k1 = loop[0];
	int k2 = loop[depth - 2];
	int flag = 0;
	double d1 = Angle(xNode[k2] - xNode[i], yNode[k2] - yNode[i],
				xNode[k1] - xNode[i], yNode[k1] - yNode[i]);
	int si;
	for(si = 1; si <= k; si++)
	{
		if(si != k1 && si != k2)
		{
			int next = connect[i][si];
			double d2 = Angle(xNode[next] - xNode[i], yNode[next] - yNode[i],
					xNode[k1] - xNode[i], yNode[k1] - yNode[i]);
			if(d2 < 0 && d2 > d1)
			{
				flag = 1; break;
			}
		}
	}
	return flag;
}

int isLoop(int a, int b)
{
	int i, j;
	loop[depth++] = b;
	if (iMask[a][b]) return 0;
	if (arrive[b]) return 0;
	arrive[b] = 1;
	iMask[a][b] = 1;
	if (b == endNode) return 1;
	int ba_x = xNode[b] - xNode[a];
	int ba_y = yNode[b] - yNode[a];
	double minAngle = 999, tempAngle;
	int bs = -1;
	for(i = 1; i <= connect[b][0]; i++)
	{
		if (connect[b][i] != a)
		{
			j = connect[b][i];
			tempAngle = Angle(xNode[j]-xNode[b], yNode[j]-yNode[b], ba_x, ba_y);
			if (minAngle>tempAngle)
			{
				minAngle = tempAngle; 
				bs = connect[b][i];
			}
		}
	}
	if(bs == -1) return 0;
	else return (isLoop(b, bs));
}

int main()
{
	int iCase;
	scanf("%d",&iCase);
	while (iCase--)
	{
		int i, j;
		int k, n, properSize;
		int node, di;
		scanf("%d",&n);
		memset(iMask, 0, sizeof(iMask));
		for(i = 0; i<n; i++)
		{
			scanf("%d",&node);
			node--;
			scanf("%d%d%d",&xNode[node], &yNode[node], &k);
			connect[node][0] = k;
			for(j = 1; j <= k; j++)
			{
				scanf("%d",&di);
				connect[node][j] = (--di);
			}
		}
		scanf("%d",&properSize);
		if(properSize < 3)
		{
			printf("0\n"); 
			continue;
		}
		int iCount = 0;
		for(i = 0; i<n; i++)
		{
			endNode = i;
			k = connect[i][0];
			for(j = 1; j <= k; j++)
			{
				depth = 0;
				memset(arrive, 0, sizeof(arrive));
				if(isLoop(i, connect[i][j]))
				{
					loop[depth] = connect[i][j];
					if(area() < 0 && isInside(i, k)==0 && depth==properSize) 
						iCount++;
				}
			}
		}
		printf("%d\n", iCount);
	}
	return 0;
}

zoj1034

#include <iostream>
using namespace std;

#define gearMax 21
#define Limit 10001

int gcd(int a,int b) {
	if (b==0) return a;
	return gcd(b,a%b);
}

int main()
{
	int gear[gearMax];
	int ratio[1200];
	bool sign[Limit];
	int iCase;
	scanf("%d", &iCase);
	for(int number=1; number<=iCase; number++) {
		int N;
		scanf("%d", &N);
		for(int i = 0; i < N; i++) 
			scanf("%d", &gear[i]);
		sort(gear, gear + N);
		for(int i = 1; i < N; i++) 
			gear[i] /= gear[0];
		memset(sign, 0, sizeof(sign));
		ratio[0] = 1;
		sign[1] = 1;
		int R = 1;
		for(int L = 0; L < R; L++) 
			for(int i = 1; i < N; i++) {
				int times = ratio[L] * gear[i];
				if(times < Limit && !sign[times]) {
					ratio[R++] = times;
					sign[times] = 1;
				}
				times = ratio[L] / gear[i];
				if( ratio[L]%gear[i]==0 && !sign[times]) {
					ratio[R++] = times;
					sign[times] = 1;
				}
			}

		printf("Scenario #%d:\n", number);
		int M;
		scanf("%d", &M);
		while(M--) {
			int a, b;
			scanf("%d%d", &a, &b);
			printf("Gear ratio %d:%d ", a, b);
			int times = gcd(a, b);
			a /= times; 
			b /= times;
			for(int i = 2; i < gearMax; i++) 
				if(b % i == 0)
					for(int j = i; j < gearMax; j += i) 
						if(sign[j]) 
							while(b % i == 0) 
								b /= i, a *= j / i;
			if(b == 1) 
				for(int i = 2; i < R && a>=Limit; i++) 
					while(a % ratio[i] == 0) 
						a /= ratio[i];
			if(b == 1 && a < Limit && sign[a]) 
				printf("can be realized.\n");
			else 
				printf("cannot be realized.\n");
		}
		printf("\n");
	}
	return 0;
}

zoj1041

#include <stdio.h>
#include <math.h>

#define MAXN 200

struct point{
	double x, y;
} c;

double distance(double x1, double y1, double x2, double y2){
	return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

double xmult(double x1, double y1, double x2, double y2){
	return (x1 * y2 - x2 * y1);
}
int main(){
	point data[MAXN]; 
	double r;
	while (scanf("%lf%lf%lf", &c.x, &c.y, &r) && r>=0 )
	{
		int n;
		scanf("%d", &n); 
		double tx, ty;
		int total = 0; 
		for (int i = 0; i<n; ++i)
		{
			scanf("%lf%lf", &tx, &ty);
			if (distance(tx, ty, c.x, c.y) <= r)
			{
				++total;
				data[total].x = tx; 
				data[total].y = ty;
			}
		}
		int best = 0;
		double sx, sy;
		for (int i = 1; i <= total; ++i)
		{
			tx = data[i].x - c.x;
			ty = data[i].y - c.y;
			int cnt = 1;
			for (int j = 1; j <= total; ++j)
			{
				if (i == j) continue;
				sx = data[j].x - c.x;
				sy = data[j].y - c.y;
				if (xmult(sx, sy, tx, ty) >= 0.00) ++cnt; 
			}
			if (cnt > best) best = cnt;
		}
		printf("%d\n", best);
	}
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值