2012 Multi-University Training Contest 9__Farmer Greedy和Quadrilateral

Problem Description
  Farmer Greedy is going to buy some houses for his farm. He has money only to buy three houses. The three houses can from a triangle area, which he can own as his farm.
  There are many houses he can choose to buy, and there are many goldstones. They are points in a 2-dimentional plane. No three points are collinear. Farmer Greedy likes odd numbers. Now Farmer Greedy wonders how many farms he can choose to have odd goldstones in it.
 

Input
  There are multiple test cases. In each case, the first line gives two integers N, M. In the next N lines, each line gives two integers (X, Y) indicating the coordinates of one house. In the next M lines, each line gives two integers (X, Y) indicating the coordinates of one goldstone.
Technical Specification
  3 <= N <= 100
  0 <= M <= 1000
  |X|, |Y| <= 100000
 

Output
  For each case, print in one line containing the case number (starting with 1) and the number of farms Farmer Greedy can choose to have odd goldstones in it.
 

Sample Input
  
  
4 4 -10 0 10 0 0 10 0 -10 1 1 1 2 -1 1 -1 -1
 

Sample Output
  
  
Case 1: 2
 

Author
WHU
 

Source

//求内部包含奇数个点的三角形的个数。本题暴力枚举复杂度为O(n^3*m)TLE。 可以从n个点中枚举每两个点组成的边投影下包含的点的个数(复杂度O(n^2*m)),最后再计算出每个三角形内部包含的点的个数(复杂度O(n^3)),总复杂度()
//对于一个三角形,设三个顶点为point p[i],p[j],p[k](可排序规定出顺序)。则有三边i->k , i->j , j->k。分别求出在三边投影下的点的个数num[i][k],num[k][j],num[i][j]. 则在三角形内部的点的个数为 abs(num[i][k]-num[i][j]-num[j][k]);
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<algorithm>
#include<ctime>
using namespace std;
#define eps 1e-8

struct point 
{
	double x,y;
};
point farm[105],stone[1005];
int n,m,used[105][105];

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

bool cmp(point a,point b)
{
	if(a.x!=b.x) return a.x<b.x;
	return a.y<b.y;
}

double x_multi(point p1,point p2,point p3)  
{
	return (p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y);
}

bool in_side(point p1,point p2,point p0)
{
	//if(p1.x>p2.x) swap(p1,p2);
	if(p0.x>=p1.x&&p0.x<p2.x&&Fabs(x_multi(p1,p2,p0))<0) //判断点在边的投影下
		return true;
	return false;
}

int in_trangle(point A,point B)
{
	int i,num=0;
	for(i=1;i<=m;i++)
		if(in_side(A,B,stone[i]))
			num++;
	return num;
}

int main()
{
	int t=0,i,j,k;
	while(~scanf("%d%d",&n,&m))
	{
		memset(used,0,sizeof(used));
		for(i=1;i<=n;i++)
			scanf("%lf%lf",&farm[i].x,&farm[i].y);
		sort(farm+1,farm+n+1,cmp);
		for(i=1;i<=m;i++)
			scanf("%lf%lf",&stone[i].x,&stone[i].y);
		for(i=1;i<=n;i++)
			for(j=i+1;j<=n;j++)
				used[i][j]=in_trangle(farm[i],farm[j]);
		int ans=0;
		for(i=1;i<=n;i++)
			for(j=i+1;j<=n;j++)
				for(k=j+1;k<=n;k++)
					if(abs(used[i][k]-used[j][k]-used[i][j])&1)
						ans++;
		printf("Case %d: %d\n",++t,ans);
	}
	return 0;
}

Quadrilateral

Problem Description
  One day the little Jack is playing a game with four crabsticks. The game is simple, he want to make all the four crabsticks to be a quadrilateral, which has the biggest area in all the possible ways. But Jack’s math is so bad, he doesn’t know how to do it, can you help him using your excellent programming skills?
 

Input
  The first line contains an integer N (1 <= N <= 10000) which indicates the number of test cases. The next N lines contain 4 integers a, b, c, d, indicating the length of the crabsticks.(1 <= a, b, c, d <= 1000)
 

Output
  For each test case, please output a line “Case X: Y”. X indicating the number of test cases, and Y indicating the area of the quadrilateral Jack want to make. Accurate to 6 digits after the decimal point. If there is no such quadrilateral, print “-1” instead.
 

Sample Input
   
   
2 1 1 1 1 1 2 3 4
 

Sample Output
   
   
Case 1: 1.000000 Case 2: 4.898979
 

Author
WHU
 

Source
//一直四边形的四条边,求该四边形能得到的最大面积。
//百度提供:已知四条边和两个对角,四边形面积公式为:S2=(p-a)(p-b)(p-c)(p-d)-abcd cos2A 
其中p=(a+b+c+d)/2,A=两个对角和之半。
从公式可知当A为90°时面积最大。这时的四边形是圆内接四边形。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<map>
#include<stack>
#include<vector>
#include<ctime>
using namespace std;

int main()
{
	int T,t=0;
	scanf("%d",&T);
	double a,b,c,d,p;
	while(T--)
	{
		scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
		p=(a+b+c+d)/2;
		printf("Case %d: ",++t);
		if(p<=a||p<=b||p<=c||p<=d)
		{
			puts("-1");
			continue;
		}
		double ans=sqrt((p-a)*(p-b)*(p-c)*(p-d));
		printf("%.6lf\n",ans);
	}
	return 0;
}	


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值