中国石油大学 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)² +(3n)+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;
}
下一篇: PTA 习题7-5 找鞍点 (20分)