CSP历年复赛题-P2239 [NOIP2014 普及组] 螺旋矩阵
原题链接:https://www.luogu.com.cn/problem/P2239
题意解读:计算螺旋矩阵的第i行j列的数。
解题思路:
1、模拟法
按照螺旋矩阵的数字增长方向,依次枚举
定义四个方向(右、下、左、上)的坐标变换int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0}
初始方向为int dir = 0,按照初始方向进行坐标变换,一直到坐标越界或者前面的坐标已经走过,则变换方向dir = (dir + 1) % 4
每变换一次坐标,进行数字++,对矩阵填充数字,比较坐标是否是目标i,j,是则输出数字
前50%的矩阵大小n<=100,可以得到50分。
50分代码:
#include <bits/stdc++.h>
using namespace std;
int n, i, j;
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
int a[1005][1005];
int main()
{
cin >> n >> i >> j;
int dir = 0, ans = 1;
int x = 1, y = 1;
a[1][1] = 1;
while(!(x == i && y == j))
{
int nx = x + dx[dir], ny = y + dy[dir];
if(a[nx][ny] != 0 || nx < 1 || nx > n || ny < 1 || ny > n)
{
dir = (dir + 1) % 4;
continue;
}
ans++;
a[nx][ny] = ans;
x = nx, y = ny;
}
cout << ans;
return 0;
}
2、位置分析法
观察得知:矩阵最外圈的数字一共有n * 4 - 4个,往里一圈为(n - 2) * 4 - 4个,直到n-2=1则只有1个
对于给定的(i,j),如果能确定其所在圈层的边长w,那么更外层的数字可以通过边长枚举计算得出,然后对于边长w的圈层进行单独枚举即可
例如:
左图白色位置坐标(5, 3),计算所在圈层的边长方法为:
矩阵长度是6,分别计算(5, 3)在行坐标、列坐标上与中心线对称的行、列左标
对称的行坐标:6 - 5 + 1 = 2,对称的列坐标:6 - 3 + 1 = 4,所以(5, 3)所在的圈层边长应该是
max(abs(行左标-对称行坐标) + 1, abs(列坐标-对称列坐标) + 1) = max(4, 2) = 4
从n = 6开始枚举每一圈,如果n > 4,则数字直接累计当前圈层的数量,每一圈之后n -= 2,当n=4时,假设一共减了k次2,开始从(k+1,k+1)按螺旋形枚举每一个位置,直到(i,j)为止。
100分代码:
#include <bits/stdc++.h>
using namespace std;
int n, i, j, ans;
int main()
{
cin >> n >> i >> j;
int i2 = n - i + 1; //对称的行坐标
int j2 = n - j + 1; //对称的列坐标
int w = max(abs(i2 - i) + 1, abs(j2 - j) + 1); //(i,j)所在圈层的边长
int k;
for(k = 1; n != w; k++,n-=2)
{
ans += n * 4 - 4; //累计(i,j)以外圈层的数字个数
}
int x = k, y = k; //从(k,k)开始螺旋遍历边长为w的圈层
ans++; //(k,k)对应的数字
if(x == i && y == j)
{
cout << ans;
return 0;
}
//向右
for(int k = 1; k < w; k++)
{
ans++; y++;
if(x == i && y == j)
{
cout << ans;
return 0;
}
}
//向下
for(int k = 1; k < w; k++)
{
ans++; x++;
if(x == i && y == j)
{
cout << ans;
return 0;
}
}
//向左
for(int k = 1; k < w; k++)
{
ans++; y--;
if(x == i && y == j)
{
cout << ans;
return 0;
}
}
//向上
for(int k = 1; k < w - 1; k++)
{
ans++; x--;
if(x == i && y == j)
{
cout << ans;
return 0;
}
}
return 0;
}
分类:
CSP-J复赛真题解析
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!