您的位置:首页 > 大数据 > 人工智能

ZOJ-3414-Trail Walk_计算几何

2014-07-17 10:45 519 查看
我打代码这么狗还这么懒,以后怎么办。

题意:

给n个点的坐标(整数),以坐标系原点为起点,依次连接各个点,给出正整数m,要求添加m个CP点(check point),把折线按长度平均分开(把起点考虑为第0个和第m+1个CP点)。

Input

There are multiple test cases. The first line of each case contains two integer n, m(1 <= n, m <= 1000). Then n pairs of integer followed,
giving the coordinate of pi.

Output

The first line of each case, output "Route case_number", Then m lines followed, the ith line contains "CPcase_num: (xi, yi)"
where (xi, yi) represent the coordinate of the CPi. Always keep three number after the decimal point.

Sample Input

3 3
1 1
2 3
3 5

Sample Output

Route 1
CP1: (1.026, 1.051)
CP2: (1.684, 2.368)
CP3: (2.342, 3.684)


计算几何里应该不难的题吧,但是由于我计算几何就是狗,而且有点新感悟就写一下。

大体过程只要按正常想法就能模拟出来,关键是公式,计算几何不要直接使用斜率的数值,但是可以通过把k写成(y1-y2)/(x1-x2)的形式表达出来,然后推出最后的式子以后再代数,这样就不会有使用斜率数值的误差了。

代码如下

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
#define mxn 1010
int n,m;
double len;
bool dcmp(double a,double b){
return fabs(a-b)<0.001;
}
struct point{
double x,y;
point(double _x,double _y){x=_x,y=_y;}
point(){};
}p[mxn];
struct ret{
int p_id;
double usd;
ret(int a,double b){p_id=a,usd=b;}
};
double dist(point a,point b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double deltaX(int in,double l){
return l*(p[in+1].x-p[in].x)/sqrt((p[in+1].y-p[in].y)*(p[in+1].y-p[in].y)+(p[in+1].x-p[in].x)*(p[in+1].x-p[in].x));
}
double deltaY(int in,double l){
return l*(p[in+1].y-p[in].y)/sqrt((p[in+1].y-p[in].y)*(p[in+1].y-p[in].y)+(p[in+1].x-p[in].x)*(p[in+1].x-p[in].x));
}
ret find(ret in,double tgt,int cp_id){
double tem=dist(p[in.p_id],p[in.p_id+1]);
if(tem-in.usd<=tgt||dcmp(tem-in.usd,tgt))
return find(ret(in.p_id+1,0.0),tgt-tem+in.usd,cp_id);
printf("CP%d: ",cp_id);
double delta_x=deltaX(in.p_id,tgt+in.usd);
double delta_y=deltaY(in.p_id,tgt+in.usd);
printf("(%.3lf, %.3lf)\n",p[in.p_id].x+delta_x,p[in.p_id].y+delta_y);
return ret(in.p_id,in.usd+tgt);
}
int main(){
int cs=1;
while(scanf("%d%d",&n,&m)!=EOF){
double sum=0;
p[0]=point(0.0,0.0);
for(int i=1;i<=n;++i){
scanf("%lf%lf",&p[i].x,&p[i].y);
sum+=dist(p[i-1],p[i]);
}
len=sum/(m+1);
ret start(0,0.0);
printf("Route %d\n",cs++);
for(int i=0;i<m;++i){
ret tem=find(start,len,i+1);
start=tem;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: