欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-06-07 14:42:19
...

问题链接 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

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

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

输入

第一行: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
中国石油大学 2019-2020大中小学训练赛第二场 F题 位置 【螺旋矩阵+DFS】
图: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;
}