OJ题目:click here~~
题目分析:对于当前点i ,从u = i+1开始考虑,如果能直接从i到father[u] ,u不妨碍的话,说明能够直接从i 跳到father[ u ],下面考虑u = father[ u ] ,直到不能直接从i 跳到father[ u ] , 即被u阻碍了 ,此时 i 的步数 = u 的步数 + 1(从i 到u 花1步)。
AC_CODE
typedef long long LL;
const int inf = 100000000;
struct Node
{
int x;
int y;
Node(){}
Node(int i,int j):x(i),y(j){}
};
bool judge(Node &a , Node &b , Node &c)//true为a可以到c,false为a不可以到c,被b拦住
{
return (LL)(b.y - a.y)*(c.x - a.x) < (LL)(b.x - a.x)*(c.y - a.y);
}
Node p[100002];
int ans[100002],father[100002];
int main()
{
int t , tt , n, m ,u, i , j;
cin >> tt;
for(t = 1;t <= tt;t++)
{
scanf("%d",&n);
for(i = 1;i <= n;i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
}
ans[n] = 0;
ans[n - 1] = 1;
father[n - 1] = n;
for(i = n - 2;i >= 1;i--)
{
u = i + 1;
while(u != n && judge(p[i] , p[u],p[father[u]]))
{
u = father[u];
}
father[i] = u;
ans[i] = ans[u] + 1;
}
printf("Case#%d:",t);
for(i = 1;i <= n;i++)
printf(" %d",ans[i]);
puts("");
}
return 0;
}