中国石油大学 2019-2020大中小学训练赛第二场 F题 位置 【螺旋矩阵+DFS】

问题链接 http://icpc.upc.edu.cn/problem.php?cid=1961&pid=5

题目描述

由于晨晨还没有研究出核心算法,在游戏中总是被明明击败。晨晨拿出了杀手锏进行反击,精心设计了一个大型取数字求位置的难题:NN( N是奇数)个地砖,每个上面写有一个编号,这些编号正好是1到N平方。她把这些地砖按次序从中间开始螺旋的铺垫在地上,形成一个NN的正方形。N=5时如下图:

每块地砖的位置用行列编号表示。左上的地砖位置为第一行第一列,右下的地砖位置为第N行第N列。上图中编号3的地砖在第2行第3列。

如果一块地砖在X行Y列,则位置编码为X * N+Y。例如:上图中编号是1的地址位置编码是:5 * 3+3 = 18;编号是5的地址位置编码是:5*3+4 = 19。

晨晨要明明计算,从数A的位置编码是什么。比如:N=5,A=6,为: 24

在这里插入图片描述

每次提问前,晨晨想知道正确的答案,请编程计算出位置编码。

输入

第一行:1个奇数N。
第二行:1个整数A。(0<A<=N*N)

输出

一个整数,表示编号A地砖的位置编码。
样例输入 Copy
5
20

样例输出

28

提示

数据范围:80%数据0<N<1000; 100%数据0<N<100000.

问题分析:

首先这是一个分层的矩阵,我们要找到其中的递推规律。可以先把中心的 1 给扣掉, 当输入为的数为1 的时候只需要给加一个特判即可;
将 1 看作第一层,每一环就是一层,

当矩阵在第n层时:
左上角的数值: (2n-3)² +1
右上角的数值:(2n-3)² +n +2
右下角的数值:(2n-3)² +(2n)+3
左下角的数值:(2n-3)² +(3
n)+4
在这里插入图片描述
图:qq_35339563
然后我们可以从最外层向里搜索
寻找我们键入的数在第几层,
然后四个边角的值将矩阵的每一层分为了四个区域,
从而确定他的位置 。

1 找出寻找的数字在哪一层
2 找出数字在四个区域中哪个区域
3 确定其行列

附上代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std; 
typedef long long ll;                   // a 为行, b为列。  t为要寻找的数字,  n为矩阵的目前规格 
ll t,n,a,b; 
void dfs(ll n,ll t ) {
    
    
	ll q,w,e,r,l,circle, maxn;
	maxn=n*n;                          //  该层的最大值
	l=pow((n-2),2);
	q=l+1;                             //  左上角
	w=l+1*n-1;                        //  右上角
	e=l+2*n-2;                        //   右下角
	r=l+3*n-3;                       //   左下角
	if(n==1) {
    
    
		a=1;
		b=1;
		return;
	}
	if(t>=q&&t<=maxn) {
    
                       //  如果要搜索的数字在这一层中,进入寻找。     如果不在进入下面else
		if(t>=q&&t<=w) {
    
    
			a=1;
			b=t-q+1;
		} else if(t>w&&t<=e) {
    
    
			b=n;
			a=t-(w);
		} else if(t>e&&t<=r) {
    
    
			a=n;
			b=n-(t-e)+1;
		} else {
    
    
			b=1;
			a=n-(t-r)+1;
		}
		return ;
	} else {
    
                            // 要找的数不在上一层循环中,  进入下一层, a++,b++;
		dfs(n-2,t);
		a++;
		b++;
		return ;
	}
}
int main() {
    
    
	scanf("%lld%lld",&n,&t);
	dfs(n,t);
	printf("%lld",a*n+b);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/wmy0536/article/details/103218596