POJ 计算几何入门
poj1696 Space Ant
题目链接:http://poj.org/problem?id=1696
题意:在一个二维平面上,给你n个点的坐标(Xi,Yi),已知有一条虫刚开始在(0,Ya)点,Ya为这些点中纵坐标的最小值,这只虫在这些点之间移动,只能往左走,且运动的轨迹不能有交点,每个点都要走一次,问你走这些点的轨迹,下图为一个合法的移动

思路:通过画图容易知道这样的轨迹一定存在,第一个走的点一定是纵坐标值最小的那个点(存在多个则横坐标也是最小),我们枚举每个当前的点,这个点和它前一个走过的点构成一条线段,则剩下所有没走过的点必须在这条线段左边,否则枚举的这个点就不合法,用叉积判断一下就好,注意可能有共线的情况存在。
#include <cmath>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<set>
#define eps 1e-8
#define INF 1e9*1.0
#define zero(x) (((x)>0?(x):-(x))<eps)
using namespace std;
struct point{double x,y;}p[100];
struct line{point a,b;}l[1000005];
double xmult(point p1,point p2,point p0){
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
int dot_online_in(point p,point l1,point l2){//判断点是否在直线上
return zero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps;
}
int n;
set<int> ::iterator it,ite;
int main(){
int t;
cin>>t;
while(t--){
cin>>n;
double z=1000;
int cnt;
int d=0;
int a[105],x[105];
set<int> s;
for(int i=1;i<=n;i++){
int k;
cin>>k;
cin>>p[k].x>>p[k].y;
if(p[k].y<z){
z=p[k].y;
cnt=k;
}
s.insert(k);
x[k]=k;
}
s.erase(cnt);
a[d++]=cnt;
x[cnt]=0;
while(s.size()>1){
for(int i=1;i<=n;i++)
if(x[i]!=0)
{
for(ite=s.begin();ite!=s.end();ite++){
if(*ite!=i){
if(xmult(p[i],p[*ite],p[cnt])<eps||dot_online_in(p[i],p[*ite],p[cnt]))
break;
}
}
if(ite==s.end()){
cnt=i;
s.erase(cnt);
x[cnt]=0;
a[d++]=cnt;
}
}
}
cout<<n;;
it=s.begin();
if(!s.empty())
a[d++]=*it;
for(int i=0;i<d;i++)
cout<<" "<<a[i];
cout<<endl;
}
}
题目链接: http://poj.org/problem?id=1981
题意:给你N个点的坐标,问其中最多能找到几个点在同一个单位圆内
思路:要使最多的点在圆内,则必有两个点在圆上,由于N较小,可以暴力枚举圆上的两个点,找到圆心,再判断其他点是否在圆内。
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
const int M=310;
const double eps=1e-6;
struct point
{
double x,y;
}p[M];
int n;
double dis(point a,point b)
{
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
point findcenter(point p1,point p2)
{
point p3,mid,center;
double b,c,ang;
p3.x=p2.x-p1.x;
p3.y=p2.y-p1.y;
mid.x=(p1.x+p2.x)/2;
mid.y=(p1.y+p2.y)/2;
b=dis(p1,mid);
c=sqrt(1-b);
if(fabs(p3.y)<eps)
{
center.x=mid.x;
center.y=mid.y+c;
}
else
{
ang=atan(-p3.x/p3.y);
center.x=mid.x+c*cos(ang);
center.y=mid.y+c*sin(ang);
}
return center;
}
int main(){
while((cin>>n)&&n!=0)
{
int i,j,k;
int ans=1;
for(i=0;i<n;i++)
cin>>p[i].x>>p[i].y;
for(i=0;i<n;i++)
{
int cnt;
for(j=i+1;j<n;j++)
{
if(dis(p[i],p[j])<=4.0+eps)
{
cnt=0;
point q=findcenter(p[i],p[j]);
for(k=0;k<n;k++)
{
if(dis(q,p[k])<=1.0+eps) cnt++;
}
if(ans<cnt) ans=cnt;
}
}
}
cout<<ans<<endl;
}
return 0;
}

浙公网安备 33010602011771号