HDU-4643-GSM(DFS)

Problem Description

Xiao Ming is traveling around several cities by train. And the time on the train is very boring, so Xiao Ming will use the mobile Internet. We all know that mobile phone receives the signal from base station and it will change the
base station when moving on the train. Xiao Ming would like to know how many times the base station will change from city A to city B.

Now, the problem is simplified. We assume the route of train is straight, and the mobile phone will receive the signal from the nearest base station.

Input

Multiple cases. For each case, The first line: N(3<=N<=50) - the number of cities, M(2<=M<=50) - the number of base stations. Then there are N cities with coordinates of (x, y) and M base stations with coordinates of (x, y) - (0<=x<=1000,
0<=y<=1000, both x and y is integer).Then there is a number : K, the next, there are K queries, for each query, each line, there are two numbers: a, b.

Output

For each query, tell Xiao Ming how many times the base station will change from city a to city b.

Sample Input

4 4
0 2
1 3
1 0
2 0
1 2
1 1
2 2
2 1
4
1 2
1 3
1 4
3 4

Sample Output

0
1
2
1

Hint

The train way from a to b will not cross the point with the same distance from more than 2 base stations.
(For the distance d1 and d2, if fabs(d1-d2)<1e-7, we think d1 == d2).
And every city exactly receive signal from just one base station.

Source

2013 Multi-University Training Contest 5

思路:每次获取中点的最近的基站的id,id跟哪边不一样就往哪边递归查找。

#include <stdio.h>
#define INF 99999999

int n,m,ans;
bool vis[50];
double sx[50],sy[50],ex[50],ey[50];

int get(double x,double y)//获取离该点最近的基站
{
    double mn=INF;
    int id,i;

    for(i=0;i<m;i++)
    {
        if((x-ex[i])*(x-ex[i])+(y-ey[i])*(y-ey[i])<mn)
        {
            mn=(x-ex[i])*(x-ex[i])+(y-ey[i])*(y-ey[i]);
            id=i;
        }
    }

    return id;
}

void dfs(int l,int r,double lx,double ly,double rx,double ry)//递归查找,每次获取中点的最近的基站的id,id跟哪边不一样就往哪边找。
{
    if((lx-rx)*(lx-rx)+(ly-ry)*(ly-ry)<1e-14) return;

    double x=(lx+rx)/2.0;
    double y=(ly+ry)/2.0;

    int id=get(x,y);

    if(!vis[id])
    {
        vis[id]=1;
        ans++;
    }

    if(id!=l) dfs(l,id,lx,ly,x,y);

    if(id!=r) dfs(id,r,x,y,rx,ry);
}

int main()
{
    int i,q,id1,id2;
    int from,to;

    while(~scanf("%d%d",&n,&m))
    {
        for(i=0;i<n;i++) scanf("%lf%lf",&sx[i],&sy[i]);

        for(i=0;i<m;i++) scanf("%lf%lf",&ex[i],&ey[i]);

        scanf("%d",&q);

        while(q--)
        {
            scanf("%d%d",&from,&to);

            id1=get(sx[from-1],sy[from-1]);
            id2=get(sx[to-1],sy[to-1]);

            if(id1==id2) printf("0\n");
            else
            {
                for(i=0;i<m;i++) vis[i]=0;
                vis[id1]=1;
                vis[id2]=1;
                ans=1;
                dfs(id1,id2,sx[from-1],sy[from-1],sx[to-1],sy[to-1]);
                printf("%d\n",ans);
            }
        }
    }
}

HDU-4643-GSM(DFS),布布扣,bubuko.com

时间: 2024-08-27 02:51:54

HDU-4643-GSM(DFS)的相关文章

HDU 4921 Map DFS+状态压缩+乘法计数

算最多十条链,能截取某前缀段,每种方案都可以算出一个权值,每种方案的概率都是总数分之一,问最后能构成的所有可能方案数. 对计数原理不太敏感,知道是DFS先把链求出来,但是想怎么统计方案的时候想了好久,其实因为只能取某个链的前缀,所以直接取链长加+1 然后相乘即可,当然因为会出现都是空的那种情况,要去掉,全部乘完之后,要-1 然后就是算权值了,权值等于当前加进来的点的总和 以及 等级相同的点的加成,并不是特别好算,这时候考虑每个状态下的点对全局的贡献,对,就是这个思想,用状态压缩来表示状态,然后这

hdu 4643(计算几何)

题意:容易理解 分析:切换的地点为两个基站所在直线的中垂线与两座城市所在直线的交点. 代码实现: #include <cstdio> #include <cmath> #include <algorithm> #define maxn 60 #define eps 1e-7 using namespace std; int dcmp(double x) //控制精度 { if(fabs(x)<eps) return 0; else return x<0?-1

HDU 1175 连连看(DFS)

Problem Description “连连看”相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子),而且线的转折次数不超过两次,那么这两个棋子就可以在棋盘上消去.不好意思,由于我以前没有玩过连连看,咨询了同学的意见,连线不能从外面绕过去的,但事实上这是错的.现在已经酿成大祸,就只能将错就错了,连线不能从外围绕过.玩家鼠标先后点击两块棋子,试图将他们消去,然后游戏的后台判断这两个方格能

hdu 1501 Zipper dfs

题目链接: HDU - 1501 Given three strings, you are to determine whether the third string can be formed by combining the characters in the first two strings. The first two strings can be mixed arbitrarily, but each must stay in its original order.For examp

HDU - 1175 连连看 DFS (记录方向)

连连看HDU - 1175 "连连看"相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子),而且线的转折次数不超过两次,那么这两个棋子就可以在棋盘上消去.不好意思,由于我以前没有玩过连连看,咨询了同学的意见,连线不能从外面绕过去的,但事实上这是错的.现在已经酿成大祸,就只能将错就错了,连线不能从外围绕过. 玩家鼠标先后点击两块棋子,试图将他们消去,然后游戏的后台判断这两个方格能

hdu 1455 Sticks——dfs经典的题目

http://acm.hdu.edu.cn/showproblem.php?pid=1455 题意:几根长度的棍子被分成了很多半.问合成多个长度相同的棍子,棍子长度最小是多少. 题解:很明显是dfs.所以我们首先需要找到,这些棍子可能是多长,肯定是最长的棍子的长度到所有棍子长度和之间的某个长度.找到这些可能之后就直接按照这个长度开始搜.想法是搜到和为这个长度之后记录,然后重新再搜,一直到所有棍子都分配自后就完成了. 重要的剪枝:确定每次搜索的起始位置,这个一定是确定的!!!其次就是相同长度的棍子

hdu 1241Oil Deposits(dfs模板)

题目链接—— http://acm.hdu.edu.cn/showproblem.php?pid=1241 首先给出一个n*m的字符矩阵,‘*’表示空地,‘@’表示油井.问在这个矩阵中有多少组油井区? 每个点周围的8个点都可以与之相连. 从左上角的点开始向后枚举然后dfs搜索就可以了.记得记忆化. 废话说完,上代码—— 1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <a

hdu 5798 Stabilization(dfs+巧妙利用二进制位)

题目链接:hdu 5798 Stabilization 题意: 给出一个序列Ai,可以让每个Ai异或上一个x使得最小,问最小值以及使得该值最小的最小x值 题解: 首先枚举x,然后如何来算得出的价值呢,巧妙的利用A[i]与A[i-1]的二进制位关系. 详细题解传送门 1 #include<bits/stdc++.h> 2 #define mst(a,b) memset(a,b,sizeof(a)) 3 #define F(i,a,b) for(int i=(a);i<=(b);++i) 4

hdu 5524 Subtrees dfs

Subtrees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description There is a complete binary tree with N nodes.The subtree of the node i has Ai nodes.How many distinct numbers are there of Ai? Input Th

hdu 1983(BFS+DFS) 怪盗Kid

http://acm.hdu.edu.cn/showproblem.php?pid=1983 首先,题目要求出口和入口不能封闭,那么,只要把出口或入口的周围全给封闭了那盗贼肯定无法成功偷盗,出口或入口周围最多 会有四个点,所以初始答案ans=4(没必要计算出出口或入口可以封闭的最小值,就初始为4就好),然后从一到四枚举看有没有 最小的符合条件的值, 所以先用BFS查找出至少偷到一个宝石的最小时间的路径,记录下来,然后枚举封闭路径上的点递归回去,再BFS判断是否能偷盗 成功---DFS中插入BFS