zoj数学几何(二)

zoj1081

#include <stdio.h>
#include <stdlib.h>

bool order(int a, int b, int c)
{
	return(((a<=b) && (b<=c)) || ((a>=b) && (b>=c)));
}

int x[102], y[102];
int n, m;

int inEdge(int x1, int y1) {
	int j;
	for(j=0; j<n; j++) 
		if ((x[j]-x1)*(y[j+1]-y1)-(x[j+1]-x1)*(y[j]-y1)==0)
			if (order(x[j], x1, x[j+1]))
				if (order(y[j], y1, y[j+1]))
					return 1;
	return 0;
}

int inPolygon(int x1, int y1) {
	int count = 0;
	int i, j;
	for(i=0; i<n; i++)
		if (y[i]!=y1) break;
	int dy1 = y[i]-y1;
	int dx1 = x[i]-x1;
	int dx2, dy2;
	int cross = 0;
	for(j=0; j<n; j++)
	{
		if ((++i)==n) i=0;
		dx2 = x[i]-x1;
		dy2 = y[i]-y1;
		if (dy2)
		{
			if (cross==0) cross = dx1*abs(dy2) + dx2*abs(dy1);
			if ((dy1<0 && dy2>0) || (dy1>0 && dy2<0))
				if (cross>0)  count++;
			dy1 = dy2;
			dx1 = dx2;
			cross = 0;
		}
		else  cross = x[i]-x1;
	}
	return count%2;
}

int main()
{
	int x1, y1;
	int cases = 1;
	while (scanf("%d", &n) && n)
	{
		scanf("%d", &m);
		int i;
		for(i=0; i<n; i++)
			scanf("%d%d", &x[i], &y[i]);
		x[n] = x[0];
		y[n] = y[0];
		if (cases!=1) printf("\n");
		printf("Problem %d:\n", cases++);
		for(i=0; i<m; i++)
		{
			scanf("%d%d", &x1, &y1);
			if(inEdge(x1, y1)) 
			{
				printf("Within\n");
				continue;
			}
			if (inPolygon(x1, y1)) printf("Within\n");
			else printf("Outside\n"); 
		}
	}
	return 0;
}

zoj1114

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

#define Root 0.8660254

double square(double x) {
	return x*x;
}

double dis(int k, int l,double x, double y, double side)
{ 
	return sqrt(square(1.5*side*k-x) + square(Root*side*l-y));
}

int main()
{ 
	double side,xa,ya,xb,yb;
	int ka, la;
	int kb, lb;
	while(scanf("%lf%lf%lf%lf%lf",&side, &xa, &ya, &xb, &yb) && (side||xa||ya||xb||yb))
	{
		ka = floor(2*xa/3/side);
		la = floor(2*ya/sqrt(3)/side);
		kb = floor(2*xb/3/side);
		lb = floor(2*yb/sqrt(3)/side);
		if(ka%2!=la%2)
		{ 
			if( dis(ka,la+1,xa,ya,side)>dis(ka+1,la,xa,ya,side)) ka++;
			else la++;
		}
		else if(dis(ka+1,la+1,xa,ya,side)<dis(ka,la,xa,ya,side))
		{
			ka++; la++;
		}
		if (kb%2!=lb%2)
		{ 
			if(dis(kb,lb+1,xb,yb,side)>dis(kb+1,lb,xb,yb,side)) kb++;
			else lb++;
		}
		else if(dis(kb+1,lb+1,xb,yb,side)<dis(kb,lb,xb,yb,side))
		{
			kb++; lb++;
		}
		double dA = dis(ka,la,xa,ya,side);
		double dB = dis(kb,lb,xb,yb,side);
		double length;
		if (ka==kb && la==lb)
			length = sqrt(square(xa-xb) + square(ya-yb));
		else if(fabs(ka-kb)>fabs(la-lb))
			length = fabs(ka-kb) * sqrt(3)*side + dA +dB;
		else
			length = sqrt(3)*side*(fabs(kb-ka) + (fabs(lb-la)-fabs(kb-ka))/2) + dA +dB;
		printf("%.3lf\n",length);
	}
	return 0;
}

zoj1133

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

int digit(int n)
{
	int sum = 0;
	while(n) 
	{
		sum += n%10; 
		n/=10;
	}
	return sum;
}

int isPrime(int n)
{
	if (n==2) return 1;
	if (n%2==0) return 0;
	int k = (int)sqrt(n);
	int i;
	for(i=3; i<=k; i+=2)
		if(n%i==0)
			return 0;
	return 1;
}

int smith(int n)
{
	int i;
	int temp = n;
	int sum = 0;
	int k = (int)sqrt(n);
	for(i=2; i<=k;){
		if(n%i==0)
		{
			sum += digit(i);
			n/=i;
			k = (int)sqrt(n);
			continue;
		}
		i++;
	}
	sum += digit(n);
	if (sum==digit(temp)) return 1;
	return 0;
}

int main()
{
	int n;
	while(scanf("%d",&n) && n)
	{
		while(n++)
			if(!isPrime(n) && smith(n)) break;
		printf("%d\n",n);
	}
	return 0;
}

zoj1158

#include <stdio.h>
#define ZERO 1e-4

struct interior
{	
	int x1, y1, x2, y2;
}inner[40];

struct sides
{	
	int a, b, c;
}side[40];

struct exterior
{	
	int x, y;
}outer[40];

void judge(struct interior w, struct sides *e)
{	
	e->a = w.y2-w.y1;
	e->b = w.x1-w.x2;
	e->c = w.x2*w.y1-w.x1*w.y2;
}

int main()
{
	int i, j, k;
	int x1, y1, x2, y2;
	int n;
	double tx, ty;
	int s1[40];
	
	int N;
	scanf("%d", &N);
	while (N--) 
	{	
		scanf("%d", &n);
		outer[0].x = 0;
		outer[0].y = 0;
		outer[1].x = 0;
		outer[1].y = 100;
		outer[2].x = 100;
		outer[2].y = 100;
		outer[3].x = 100;
		outer[3].y = 0;
		int sp = 3;
		for(i=0; i<n; i++)
		{	
			scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
			outer[++sp].x = x1;
			outer[sp].y = y1;
			outer[++sp].x = x2;
			outer[sp].y = y2;
			inner[i].x1 = x1;
			inner[i].y1 = y1;
			inner[i].x2 = x2;
			inner[i].y2 = y2;
		}
		scanf("%lf%lf", &tx, &ty);
		double side0;
		for(i=0; i<n; i++)
		{	
			judge(inner[i], &side[i]);
			side0 = side[i].a*tx+side[i].b*ty+side[i].c;
			if (side0>ZERO) s1[i] = 1;
			else if(side0<ZERO) s1[i] = -1;
			else s1[i] = 0;
		}
		int door;
		int minDoor = 9999;
		int side1;
		int s2;
		for(i=0; i<sp; i++)
			for(j=i+1; j<=sp; j++)
			{	
				x1 = outer[i].x+outer[j].x;
				y1 = outer[i].y+outer[j].y;
				if((x1==0)||(y1==0)||(x1==200)||(y1==200))
				{	
					door = 0;
					for(k=0; k<n; k++)
					{	
						side1 = side[k].a*x1+side[k].b*y1+2*side[k].c;
						if (side1>0) s2 = 1;
						else if(side1<0) s2 = -1;
						else
						{	
							door = 9999; break;
						}
						if (s2!=s1[k]) door++;
					}
					if (minDoor>door) minDoor = door;
				}
			}
		printf("Number of doors = %d\n", ++minDoor);
		if (N) printf("\n");	
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值