zoukankan      html  css  js  c++  java
  • NOIP2017模拟赛14 三向城

    三向城

    题目描述

    三向城是一个巨大的城市,之所以叫这个名字,是因为城市中遍布着数不尽的三岔路口。(来自取名力为0的出题人)

    具体来说,城中有无穷多个路口,每个路口有唯一的一个正整数标号。除了1号路口外,每个路口都连出正好3条道路通向另外3个路口:编号为x(x>1)的路口连出3条道路通向编号为x*2,x*2+1和x/2(向下取整)的3个路口。1号路口只连出两条道路,分别连向2号和3号路口。

    所有道路都是可以双向通行的,并且长度都为1。现在,有n个问题:从路口x到路口y的最短路长度是多少?

    输入格式

             第一行包含一个整数n,表示询问数量;

             接下来n行,每行包含两个正整数x, y,表示询问从路口x到路口y的最短路长度。

    输出格式

             输出n行,每行包含一个整数,表示对每次询问的回答。如果对于某个询问不存在从x到y的路径,则输出-1。

    样例输入

    3
    5 7
    2 4
    1 1

    样例输出

    4
    1
    0

    样例解释

             5号路口到7号路口的路径为:5->2->1->3->7,长度为4;

             2号路口到4号路口的路径为:2->4,长度为1;

             1号路口到本身的路径长度为0;

    数据范围

             对30%的数据,x,y≤20;

             对60%的数据,x,y≤105,n≤10;

             对100%的数据,x,y≤109,n≤104

     思路:

    根据题意,我们得知这是一棵满二叉树,不存在两个点不能互相到达的情况。

    做法一:

    LCA思想,我们先计算每个点的深度。首先使两个点先到达同一深度,然后同时向上跳,直到相等为止。

    代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<cmath>
    
    using namespace std;
    
    int n,a,b,da,db,ans1,ans2;
    
    long long read()
    {
        long long x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    int main()
    {
        freopen("city.in","r",stdin);
        freopen("city.out","w",stdout);
        n=read();
        for(int i=1;i<=n;++i)
        {
            a=read();b=read();
            ans1=0;ans2=0;
            double aa=a;
            double bb=b;
            da=1;db=1;
            while(aa>=1){aa/=2;if(aa>=1)da++;}
            while(bb>=1){bb/=2;if(bb>=1)db++;}
            if(da<db){swap(da,db);swap(a,b);}
            while(da!=db){da--;a>>=1;ans1++;}
            while(a!=b){a>>=1;b>>=1;ans2++;}
            printf("%d
    ",ans1+2*ans2);
        }
        return 0;
    }

    做法二:

    更优,我们反复对大的数除以2直到相等为止,答案就是操作次数

  • 相关阅读:
    读取INI配置文件
    在VB编程中,若一行代码太长需要换行时,行尾要加什么符号
    使用order by和group by的分析
    转 Sqlserver_left join 、right join、 inner join 用法
    Python 字典(Dictionary)操作详解
    转sql server新增、修改字段语句(整理)
    Winform TextBox中只能输入数字的几种常用方法(C#)
    数据库的范式,第一、二、三、四、五范式、BC范式
    【操作系统】银行家算法
    转 图解排序算法(三)之堆排序
  • 原文地址:https://www.cnblogs.com/-hhs/p/11441711.html
Copyright © 2011-2022 走看看