QDU校内排位赛第三场 K 闪电鞭曲线

题链:https://pintia.cn/problem-sets/1330210570443206656/problems/1330211663051010048

题目:

 

思路:希尔伯特曲线,直接递归球即可。按主对角线对称,交换x,y;副对角线对称,假设正方形变成为m,newx=m-y+1,newy=m-x+1。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int n,k,op;
ll x,y,xx1,yy1,xx2,yy2;
ll dfs1(int k,int x,int y){
	if(k==1){
		if(x==1&&y==1) return 1;
		else if(x==2&&y==1) return 2;
		else if(x==2&&y==2) return 3;
		else return 4; 
	}
	ll m = (1LL<<(k-1)),xx=(x-1)/m,yy=(y-1)/m,mm=m*m;
	if(xx==0&&yy==0) return dfs1(k-1,y,x);	
	else if(xx>0&&yy==0) return mm+dfs1(k-1,x-m,y);
	else if(xx>0&&yy>0) return (mm*2)+dfs1(k-1,x-m,y-m);	  
	else{
		y-=m;
		return mm*3+dfs1(k-1,m-y+1,m-x+1);	
	}
}
void dfs2(int k,ll id,ll& x,ll& y){
	if(k==1){
		if(id==1) x=1,y=1;
		else if(id==2) x=2,y=1;
		else if(id==3) x=2,y=2;
		else x=1,y=2;
		return ;
	}
	ll m = (1LL<<(k-1)),mm=m*m,xx=(id-1)/mm;
	id-=xx*mm;
	if(xx==0){
		dfs2(k-1,id,x,y);
		swap(x,y);
	}else if(xx==1){
		dfs2(k-1,id,x,y);
		x+=m;
	}else if(xx==2){
		dfs2(k-1,id,x,y);
		x+=m,y+=m;
	}else{		
		dfs2(k-1,id,x,y);
		ll t=x;
		x=m-y+1;
		y=m-t+1;
		y+=m;
	}
}
int main(void){
	scanf("%d%d",&n,&k);
	while(n--){
		scanf("%d%lld%lld",&op,&x,&y);
		if(op==1){
			printf("%lld\n",dfs1(k,x,y));
		}else{
			dfs2(k,x,xx1,yy1);
			dfs2(k,y,xx2,yy2);
			printf("%lld\n",abs(xx1-xx2)+abs(yy1-yy2));
		}	
	}	
	return 0;	
} 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值