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

Fzu 2160 Mountain climbing 模拟

2014-04-25 14:43 134 查看
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2160

题目大意:给你N座山的位置X和高度Y,如果两座山的山顶连线不和其它山相交,则从一座山至另外一坐山花费1单位时间,问你从每座山到最后一座山花费的时间。

解题思路:假设山为a,b,。。。,刚开始读完题一直以为必须a的高度比b高且a,b的山顶连线不和其它山相交,才能花费一单位时间过去,后来才知道高度无限制。那现在高度无限制,我们就从最后一座山N开始向前找,找到每座山X到最后一座山N的时间,同时记录X能直接到达的最远的山的位置next【X】,下次再访问完X之后直接访问next【X】就行了,当到某座山x之后不能一步到达后面的山,那么时间就是1+step【x】;因为从当前山到x只需要1时间,而从x到N在前面已经计算出来了。

同时需要说的是:对于三点坐标,如何判断中间点b与线段ab的关系?

如果(b.y-a.y)*(c.x-b.x)-(b.x-a.x)*(c.y-b.y)<0 说明b点在线段ac的下方;

如果(b.y-a.y)*(c.x-b.x)-(b.x-a.x)*(c.y-b.y)=0 说明b点在线段ac的上;

如果(b.y-a.y)*(c.x-b.x)-(b.x-a.x)*(c.y-b.y)<0 说明b点在线段ac的上方;

代码如下:

#include<stdio.h>
#include<string.h>
struct node{
__int64 x,y,next,step;//x,y为坐标,next为当前点能到达最远点的坐标,step为到达最后一座山的时间
}s[100002];
bool judge(node a,node b,node c)//判断点b相对于a,c连线的位置
{
if((b.y-a.y)*(c.x-b.x)-(b.x-a.x)*(c.y-b.y)<0)
return true;
return false;
}
int main()
{
int T,n,cnt=1;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%I64d%I64d",&s[i].x,&s[i].y);
s
.step=0;
s[n-1].step=1;
s[n-1].next=n;
for(int i=n-2;i>0;i--)
{
int temp=i+1;
while(temp<n&&judge(s[i],s[temp],s[s[temp].next]))
temp=s[temp].next;//找到第一个无法直接到达的点
s[i].next=temp;//更新当前点的next
s[i].step=s[temp].step+1;
}
printf("Case#%d:",cnt++);
for(int i=1;i<=n;i++)
printf(" %I64d",s[i].step);
printf("\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: