DTZS-Round1-T5-数阵查询

黑大帅 2025-5-6 20:05:03 17 浏览 0 点赞 0 收藏

解析

首先看到题目我们可以发现,或者应该要发现,变化nn次的 这个矩阵的规模是多大;

根据题意的变化规律:

  • 当前有数字的方阵填充成 2×22 \times 2 的大方阵:
  • 在其方阵的右边界和下边界填上当前数阵没有的最小正整数。

不难发现,每多变化一次,规模是 ×2+1\times 2 + 1的,所以显然可以得到递推式:

di d_i 为 变化ii次的规模,初始条件 d0d_0 = 1

递推式: di=di1×2+1d_i = d_{i - 1} \times 2 + 1

然后思考什么情况下是无解的呢?

不难发现,当前给的x,yx,y是超出变化nn次的规模的,显然是无解的

直接输出11-1 \quad -1;

那么对于有解的情况怎么思考呢?

有解的情况可以分为两类:

  1. 如果x,yx,y刚好处于当前变化的这一层的边界上,那么答案就是 n+1n + 1

    也就是以下情况:

2.如果x,yx,y不处于当前变化的这一层的边界上

也就是以下情况的其中一种:

不难发现,我们其实都可以把 x,yx,y映射到 AA区域去,因为B,C,DB,C,D三个区域是由A区域变化过来的;

所以如果处于A区域,不需要变化;

如果不处于,直接做映射,然后发现,将x,yx,y映射到AA区域,其实就是找到变化次数 少一次的 对应的位置;

这个时候,我们就不难想到递归了,将当前x,yx,y转移传递到 上一层的 对应的节点的位置

设映射后的位置为x,yx',y'

  • 处于DD区域 \rightarrow AA, x=xdn1,y=ydn1x' = x - d_{n - 1},y' = y - d_{n - 1}
  • 处于CC区域 \rightarrow AA, x=xdn1,y=yx' = x - d_{n - 1},y' = y
  • 处于BB区域 \rightarrow AA, x=x,y=ydn1x' = x,y' = y - d_{n - 1}
  • 处于AA区域 \rightarrow AA, x=x,y=yx' = x ,y' = y

然后规模缩小一层,变成 大问题的子问题,直接递归即可

参考代码

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
ll b[45];
ll work(ll n , ll x , ll y){
	if(x > b[n] || y > b[n]) return -1;
	if(x == b[n] || y == b[n]) return n + 1;
	ll x1 = x , y1 = y;
	if(x > b[n-1]) x1 = x-b[n-1];
	if(y > b[n-1]) y1 = y-b[n-1];
	return work(n-1,x1,y1);
}
int main(){
	b[0] = 1;
	b[1] = 3;
	for(int i = 2;i <= 20;i++){
		b[i] = b[i-1] * 2 + 1;
	}
	
	int t;
	cin >> t;
	while(t--){
		ll n,x,y;
		cin >> n >> x >> y;
		
		
		cout << work(n,x,y) << "\n";
	}

	return 0;
}

评论

0 条
还没有评论。