zoukankan      html  css  js  c++  java
  • hdu3830(lca + 二分)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3830

    题意: 有三个点 a, b, c, 对于其中任意一点 x 可以跨过一个点移动到另一个位置, 当且仅当移动前后的 x 与其所跨越的点的距离相等 .给出两组点, 问其能否相互到达, 若能并输出最少需要移动多少步 .

    思路: http://www.cnblogs.com/scau20110726/archive/2013/06/14/3135024.html

    代码:

      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <algorithm>
      4 #define ll long long
      5 using namespace std;
      6 
      7 struct node{
      8     ll x, y, z, d;
      9 };
     10 
     11 void f(node &s){
     12     ll cnt[3];
     13     cnt[0] = s.x;
     14     cnt[1] = s.y;
     15     cnt[2] = s.z;
     16     sort(cnt, cnt + 3);
     17     s.x = cnt[0];
     18     s.y = cnt[1];
     19     s.z = cnt[2];
     20 }
     21 
     22 bool equal(node a, node b){//判断两个节点是否想等
     23     if(a.x == b.x && a.y == b.y && a.z == b.z) return true;
     24     return false;
     25 }
     26 
     27 node get_root(node &root){//这里要记录一下深度
     28     ll r;
     29     node cnt = root;
     30     ll p = cnt.y - cnt.x;
     31     ll q = cnt.z - cnt.y;
     32     while(p != q){
     33         if(q > p){ //右边大于左边
     34             r = (q - 1) / p;
     35             cnt.x += r * p;
     36             cnt.y += r * p;
     37         }else{
     38             r = (p - 1) / q;
     39             cnt.z -= r * q;
     40             cnt.y -= r * q;
     41         }
     42         root.d += r;
     43         f(cnt); //注意每个节点都要维护
     44         p = cnt.y - cnt.x;
     45         q = cnt.z - cnt.y;
     46     }
     47     return cnt;
     48 }
     49 
     50 node get_pre(node cnt, ll step){ //返回cnt向上移动step步后到达的位置
     51     ll p, q, r;
     52     while(step > 0){
     53         p = cnt.y - cnt.x;
     54         q = cnt.z - cnt.y;
     55         if(q > p){
     56             r = (q - 1) / p;
     57             if(r > step) r = step;//注意剩余步数不足的情况
     58             cnt.x += r * p;
     59             cnt.y += r * p;
     60         }else{
     61             r = (p - 1) / q;
     62             if(r > step) r = step;
     63             cnt.z -= r * q;
     64             cnt.y -= r * q;
     65         }
     66         step -= r;
     67         f(cnt);
     68     }
     69     return cnt;
     70 }
     71 
     72 ll solve(node s, node e){
     73     ll l = 0, r = s.d < e.d ? s.d : e.d;
     74     ll cnt = r;
     75     while(l <= r){
     76         ll mid = (l + r) >> 1;
     77         ll gg = cnt - mid;// mid 为 lca 位置, gg 为移动步数
     78         if(equal(get_pre(s, gg), get_pre(e, gg))) l = mid + 1;
     79         else r = mid - 1;
     80     }
     81     return ((cnt - (l - 1)) << 1);// l - 1 为lca位置
     82 }
     83 
     84 int main(void){
     85     node s, e;
     86     while(~scanf("%lld%lld%lld%lld%lld%lld", &s.x, &s.y, &s.z, &e.x, &e.y, &e.z)){
     87         s.d = e.d = 0;
     88         f(s);
     89         f(e);
     90         if(!equal(get_root(s), get_root(e))){ //根节点不同无法到达
     91             puts("NO");
     92             continue;
     93         }
     94         ll d = abs(s.d - e.d);
     95         if(s.d > e.d) s = get_pre(s, d); //使两者处于同一深度
     96         else e = get_pre(e, d);
     97         int sol = solve(s, e);
     98         puts("YES");
     99         printf("%lld
    ", d + sol);
    100     }
    101     return 0;
    102 }
    View Code
  • 相关阅读:
    openssl rsautl和openssl pkeyutl(文件的非对称加密)
    Card Stacking 队列模拟
    poj 2456 Aggressive cows 贪心+二分
    E. MaratonIME does (not do) PAs
    B. Yet Another Crosses Problem
    hdu 2578 Dating with girls(1) 满足条件x+y=k的x,y有几组
    poj 3262 Protecting the Flowers 贪心 牛吃花
    hdu 1789 Doing Homework again 贪心
    贪心总结
    E. Third-Party Software
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/7282559.html
Copyright © 2011-2022 走看看