【分治】poj 8463 Stupid cat & Doge

题目见:http://noi.openjudge.cn/ch0204/8463/

解题思路:利用左上、右上、左下、右下和上一等级横、纵坐标之间的关系,比如左上的横坐标等于上一等级的纵坐标,左上的纵坐标等于上一等级的横坐标,建立递推关系。

注意点:
1、数据较大,采用long long数据单元
2、结果需要四舍五入,调用round函数

代码如下:

#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;

long long map[2][5] = { -1, 0, 0, 1, 1, -1, 0, 1,1,0 };

long long decide(int l, long long m) {
    long long area = pow(2, 2 * l)/4;
    long long temp = (m - 1) / area;
    return temp + 1;
}
long long count_y(int l, long long m);
long long count_x(int l, long long m) {
    if (l == 1) {
        return map[0][m];
    }
    long long temp = decide(l, m);
    long long sum = pow(2, 2 * l);
    long long a = pow(2, l-1);
    if (temp == 1) {
        return count_y(l - 1, m);
    }
    if (temp == 2)
        return count_x(l - 1, m - sum / 4);
    if (temp == 3) {
        return a + count_x(l - 1, m-sum/4 * 2);
    }
    return a + a - 1 - count_y(l - 1, sum + 1 - m);
}

long long count_y(int l, long long m) {
    if (l == 1) {
        return map[1][m];
    }
    int temp = decide(l, m);
    long long sum = pow(2, 2 * l);
    long long a = pow(2, l - 1);
    if (temp == 1) {
        return count_x(l - 1, m);
    }
    if (temp == 2)
        return a + count_y(l - 1, m - sum / 4);
    if (temp == 3) {
        return a + count_y(l - 1, m - sum / 4 * 2);
    }
    //cout << " jjujj" << count_x(l - 1, sum + 1 - m) << endl;
    return count_x(l - 1, sum + 1 - m);
}

int main() {
    int num;
    int level;
    long long m, n;
    cin >> num;
    while (num--) {
        cin >> level >> m >> n;
        long long m_x = count_x(level, m);
        long long m_y = count_y(level, m);
        long long n_x = count_x(level, n);
        long long n_y = count_y(level, n);
        //cout << m_x << " " << m_y << " " << n_x << " " << n_y << endl;
        long long dis = round(sqrt(pow((m_x - n_x) * 10, 2) + pow((m_y - n_y) * 10, 2)));
        cout << dis << endl;
    }
    //system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值