poj3889

写的时候注意规律。。。。有点像波利亚变换的一些东西,当然并没用,知不知道都无所谓。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
typedef unsigned long long ll;
typedef long double llb;
ll getpr[380][2][5],getpl[380][2][5];
ll kindd[4], anglee[2][4];
int n;
void copy(int angle)
{
	for (int i = 0, k = 3; i <= 3; i++, k--)
	{
		getpr[angle][1][i] = getpr[angle][0][k];
		getpl[angle][1][i] = getpl[angle][0][k];
	}
}
void rot(int angle1, int angle2)
{
	for (int i = 0, k = 3; i < 4; i++, k++)
	{
		getpr[angle2][0][i] = getpr[angle1][0][k%4];
		getpl[angle2][0][i] = getpl[angle1][0][k%4];
	}
}
void init()
{
	kindd[0] = kindd[3] = 1;
	kindd[1] = kindd[2] = 0;
	anglee[0][0] = 270; anglee[0][3] = 90;
	anglee[0][1] = anglee[0][2] = 0;
	anglee[1][0] = 90; anglee[1][3] = 270;
	anglee[1][1] = anglee[1][2] = 0;
	getpr[0][0][0] = 0; getpl[0][0][0] = 0;
	getpr[0][0][1] = 0; getpl[0][0][1] = 1;
	getpr[0][0][2] = 1; getpl[0][0][2] = 1;
	getpr[0][0][3] = 1; getpl[0][0][3] = 0;
	copy(0);
	rot(0, 90);
	copy(90);
	rot(90, 180);
	copy(180);
	rot(180, 270);
	copy(270);
}
struct pairr
{
	ll r, l;
};
pairr searchh(ll kind, ll numl, ll numr, int angle, ll aim,ll row1,ll line1,int n)
{
	if ((numr - numl + 1)== 4)
	{
		int rank = 0;
		while (aim != numl)
		{
			rank++; numl++;
		}
		pairr c;
		c.r = row1 + getpr[angle][kind][rank];
		c.l = line1 + getpl[angle][kind][rank];
		return c;
	}
	else
	{
		ll r[5];
		ll l[5];
		r[0] = row1;
		r[1] = row1 + ((ll)1 << (n-1));
		l[0] = line1;
	    l[1] = line1 + ((ll)1 << (n-1));
		ll numll[4];
		ll numrr[4];
		ll len = (numr - numl + 1) / 4;
		numll[0] = numl; numrr[0] =numll[0] + len - 1;
		for (int i = 1; i < 4; i++)
		{
			numll[i] = numll[i - 1] + len;
			numrr[i] = numll[i] + len - 1;
		}
		int rankk = 0;
		while (1)
		{
			if (aim >= numll[rankk] && (aim <= numrr[rankk]))
				break;
			rankk++;
		}
		return searchh(kind^kindd[rankk], numll[rankk], numrr[rankk], (angle + anglee[kind][rankk]) % 360, 
			aim, r[getpr[angle][kind][rankk]], l[getpl[angle][kind][rankk]],n-1);
	}
}
ll getans(llb ans)
{
	ll k = (ll)ans;
	if (ans - k < 0.5)
		return k;
	else
		return k + 1;
}
ll c;
int main()
{
	init();
	int t;
	scanf("%d", &t);
	int a, b, c;
	while (t--)
	{
		scanf("%d%d%d", &a, &b, &c);
		n = a;
		pairr k1, k2;
		k1 = searchh((ll)0, 1, (ll)1 << (n*2), 0, b, 1, 1, n);
		k2 = searchh((ll)0, 1, (ll)1 << (n*2), 0, c, 1, 1, n);
		llb q1 = fabs((llb)k1.r - (llb)k2.r);
		llb q2 = fabs((llb)k1.l - (llb)k2.l);
		q1 = sqrt(q1*q1 + q2*q2);
		q1 *= 10;
		printf("%lld\n", getans(q1));
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值