hdu 4885 TIANKENG’s travel (最短路+判断三点共线)

TIANKENG’s travel

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 408    Accepted Submission(s): 100

Problem Description

TIANKENG has get a driving license and one day he is so lucky to find a car. Every day he drives the car around the city. After a month TIANKENG finds that he has got high driving skills and he wants to drive home. Assuming that we
regard the map of Hangzhou as a two-dimensional Cartesian coordinate system, the coordinate of the school is (sx, sy), the coordinate of TIANKENG’s home is (ex,ey). There are n gas stations distributing along the road and the coordinate of the ith gas station
is (xi, yi). Because there is something wrong with the car engine, TIANKENG can drive the car for L miles after every time he fills up the gas. Assuming that TIANKENG must fill up the gas when he passes by a gas station and the initial status of the tank is
full. TIANKENG must drive on the straight line and he can only choose to drive to school or home or gas station. Your task is to tell TIANKENG the minimum times he needs to charge fuel to go home successfully.

Input

The first line contains a positive integer T(T<=30), referring to T test cases.

For each test case, the first line contains two integers n(0<=n<=1000), L(1<=L<=100000), which mean n gas stations in all and the distance TIANKENG can drive with the full tank respectively. The second line contains two integers sx, sy, which refers to the
coordinate of the school.

The third line contains two integers ex, ey, which refers to the coordinate of TIANKENG’s home.

Then following n lines, each line contains two integer xi, yi, which refers to the coordinate of gas station.

Assuming that all the coordinates are different! All the coordinates satisfied [0,1000000].

Output

For each test case, if TIANKENG cannot go home successfully, print “impossible”(without quotes), otherwise print the minimum times of charging fuel.

Sample Input

2
2 1000
0 0
2000 1000
1000 0
2000 0
0 1000
0 0
2000 1000

Sample Output

2
impossible

Source

BestCoder Round #2

题意:

给你一个起点,一个终点和一些加油站,你只能走直线,只能到达这三种点,经过加油站必须加油,一次加油可以走L的距离,问最少经过加油站几次可以从起点到达终点。

思路:

一个点与直接能走到的点建边(不穿过其他点),然后求最短路就够了。要判断两点共线,采用的方法是枚举每个点为起始点(只与y大于它的带你建边),用map来维护这个点所在线的斜率(出发变为乘法),用一个数组记录这个斜率下的最小的y的id。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <map>
#include <algorithm>
#define INF 0x3f3f3f3f
#define maxn 1005
#define MAXN 2000005
#define eps 1e-10
typedef long long ll;
using namespace std;

ll n,m,ans,cnt,sx;
bool vis[maxn];
ll dist[maxn],head[maxn],id[maxn][maxn];
struct node
{
    ll x,y,id;
    bool operator <(const node n1)const
    {
        if(x*n1.x>=0) return  y*n1.x<n1.y*x;
        return y*n1.x>n1.y*x;
    }
}q[maxn],cur;
struct Node
{
    ll v,w,next;
}edge[MAXN];

void addedge(ll u,ll v,ll w)
{
    cnt++;
    edge[cnt].v=v;
    edge[cnt].w=w;
    edge[cnt].next=head[u];
    head[u]=cnt;
}
ll cal(ll i,ll j)
{
    ll xx=q[i].x-q[j].x,yy=q[i].y-q[j].y;
    return xx*xx+yy*yy;
}
void SPFA()
{
    ll i,j,nx,v;
    memset(vis,0,sizeof(vis));
    memset(dist,0x3f,sizeof(dist));
    sx=1;
    queue<ll>q;
    dist[sx]=0;
    vis[sx]=1;
    q.push(sx);
    while(!q.empty())
    {
        nx=q.front();
        vis[nx]=0;
        q.pop();
        for(i=head[nx];i;i=edge[i].next)
        {
            v=edge[i].v;
            if(dist[v]>dist[nx]+edge[i].w)
            {
                dist[v]=dist[nx]+edge[i].w;
                if(!vis[v])
                {
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
}
void solve()
{
    ll i,j,t;
    for(i=1;i<=n;i++)
    {
        map<node,ll>mp;
        ll tot=0;
        for(j=1;j<=n;j++)
        {
            if(q[j].y<q[i].y||q[j].y==q[i].y&&q[j].x<=q[i].x||cal(i,j)>m*m) continue ;
            cur.y=q[j].y-q[i].y;
            cur.x=q[j].x-q[i].x;
            t=mp[cur];
            if(t==0)
            {
                mp[cur]=++tot;
                id[i][tot]=j;
            }
            else
            {
                if(q[id[i][t]].y>q[j].y||q[id[i][t]].y==q[j].y&&q[id[i][t]].x>q[j].x)
                {
                    id[i][t]=j;
                }
            }
        }
        for(j=1;j<=tot;j++)
        {
            //printf("u:%I64d v:%I64d\n",i,id[i][j]);
            addedge(i,id[i][j],1);
            addedge(id[i][j],i,1);
        }
    }
}
int main()
{
    ll i,j,u,v,w,t;
    scanf("%I64d",&t);
    while(t--)
    {
        scanf("%I64d%I64d",&n,&m);
        n+=2;
        for(i=1;i<=n;i++)
        {
            scanf("%I64d%I64d",&q[i].x,&q[i].y);
            q[i].id=i;
        }
        cnt=0;
        memset(head,0,sizeof(head));
        solve();
        SPFA();
        if(dist[2]>=INF) printf("impossible\n");
        else printf("%I64d\n",dist[2]-1);
    }
    return 0;
}
/*
2
3 4
1 1
4 1
3 1
2 1
2 4

6 4
5 5
1 1
2 4
4 4
3 3
4 3
2 2
3 1
*/

hdu 4885 TIANKENG’s travel (最短路+判断三点共线)

时间: 2024-07-29 22:06:06

hdu 4885 TIANKENG’s travel (最短路+判断三点共线)的相关文章

HDU 4885 TIANKENG’s travel 最短路

判断是否共线用map记录下斜率: #include <stdio.h> #include <string.h> #include <stdlib.h> #include <limits.h> #include<algorithm> #include<math.h> #include<map> using namespace std; #define N 1022 const int INF = 1<<30-1;

hdu 4885 TIANKENG’s travel(bfs)

题目链接:hdu 4885 TIANKENG's travel 题目大意:给定N,L,表示有N个加油站,每次加满油能够移动距离L,必须走直线,可是能够为斜线.然后给出sx,sy,ex,ey,以及N个加油站的位置,问说最少经过几个加油站,路过不加油也算. 解题思路:一開始以为经过能够不算,所以o(n2)的复杂度建图,然后用bfs求最短距离,结果被FST了. 将点依照x坐标排序,这样在建图是保证当前点为最左点,每次建立一条边的时候,将该边的斜率记录,下次有同样的斜率则不加边,斜率能够用两个整数表示,

[ACM] HDU 4885 TIANKENG’s travel (特殊建图,最短路)

TIANKENG's travel Problem Description TIANKENG has get a driving license and one day he is so lucky to find a car. Every day he drives the car around the city. After a month TIANKENG finds that he has got high driving skills and he wants to drive hom

hdu 4885 (n^2*log(n)判断三点共线建图)+最短路

题意:车从起点出发,每次只能行驶L长度,必需加油到满,每次只能去加油站或目的地方向,路过加油站就必需进去加油,问最小要路过几次加油站. 开始时候直接建图,在范围内就有边1.跑最短了,再读题后发现,若几个点共线,且都在范围内,那么中间有点的俩头的点就不能有边,否则与条件相悖.关键是怎么用n^2*logn,的复杂度判断三点共线:点先按X排序,考察每个点i时候,第二个点j,若直线ij斜率已经存在,则不能添加了,查找是否存在,用容器就行(map\set)都是logn的,所以满足要求.之后最短路即可. #

HDU5020(判断三点共线)BestCoder Round #10(1003)

Revenge of Collinearity Time Limit: 8000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 184    Accepted Submission(s): 51 Problem Description In geometry, collinearity is a property of a set of points, specifi

hdu 4886 TIANKENG’s restaurant(Ⅱ) (hash)

题目大意: 求出在文本串中第一个没出现的字典序最小的串.. 思路分析: 开始的时候 用后缀数组写,然后根据sa的有序性.你就可以知道哪个串没有出现了. 但是题目卡了倍增哦... 自习想一想的话,我们用 sa 数组,也就是想知道这个串有没有出现过,也就是判断重复,却浪费了  O (n * lg n)... 判断重复为什么没想到hash . 把每一个长度的子串都hash 出来,用八进制表示,这样的话就可以得到一个递增的hash值. 将之存入hash 数组.找到第一个空的hash的下标,就是第一个没出

hdu 1690 Bus System(Dijkstra最短路)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1690 Bus System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6569    Accepted Submission(s): 1692 Problem Description Because of the huge popula

hdu 4883 TIANKENG’s restaurant(暴力)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4883 Problem Description TIANKENG manages a restaurant after graduating from ZCMU, and tens of thousands of customers come to have meal because of its delicious dishes. Today n groups of customers come t

HDU 4883 TIANKENG’s restaurant Bestcoder 2-1(模拟)

TIANKENG's restaurant Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 0    Accepted Submission(s): 0 Problem Description TIANKENG manages a restaurant after graduating from ZCMU, and tens of t