wow!蛇形矩阵!但是看到最后一行我就吐血了......

本文介绍了一种解决大规模蛇形矩阵中特定数值k所在位置的高效算法,避免了直接填充矩阵的低效方法。通过将矩阵分为斜线并计算每条斜线的起点,利用数学公式确定k的位置,从而在给定的n和k条件下快速找到答案。代码实现详述了整个过程,适用于处理大范围的数据输入。
摘要由CSDN通过智能技术生成

(本人是小学生哟!)
今天看到了一道特别BT的题目,蛇形矩阵。
【问题描述】(本题所有的矩阵,就相当于数字填入一个正方形)
一个n行n列的蛇形矩阵可由如下方法生成:
从矩阵的左上角(第1行第1列)出发,初始时向右移动一格,然后向左下移动,直到碰到边界;如果下方是在范围内未出界的格子,则向下移动一格接着往右上移动,否则向右移动一格接着往右上移动,直到到达边界;接着,如果右边的格子在范围内,往右移动一格,否则向下移动一格,接着往左下直到边界;重复上述操作直至经过矩阵中所有格子。根据经过顺序,在格子中依次填入1, 2, 3, … , n*n,便构成了一个蛇形矩阵。
下图是一个n = 4 时的蛇形矩阵。
在这里插入图片描述
现给出矩阵大小n以及k,请你求出该矩阵中k值所在位置的行号和列号(行号列号都从1开始)。

输入
第一行两个整数n和k,分别表示矩阵的行数和要求位置的数值k。

输出
输出一行两个整数,表示k在矩阵中的行号和列号,中间用一个空格分隔。
样例输入
4 5

样例输出
2 2

【样例1解释】
44的矩阵如下:5位于第二行第二列。
1 2 6 7
3 5 8 13
4 9 12 14
10 11 15 16
数据范围限制
【数据范围】
对于70%的数据,1≤n≤100;
对于100%的数据,1≤n≤30,000,1≤k≤n
n。

1≤n≤30,000
30000!!!
30000*30000=900000000
int a[30000][30000];
于是…
在这里插入图片描述
所以这道题要强行去找肯定是不行的。
怎么办呢?
我(智商滑坡者)的思路:
1.先把矩阵分成很多条斜线:
在这里插入图片描述
2.循环2n-1次,每次确定开头的横坐标和纵坐标,如果累加到的sum>k,那么就可以看看k离起点有多远,最后就可以确定k的坐标并输出了!
话不多说,上代码!

#include<bits/stdc++.h>
using namespace std;
int sum,n,k,ansx,ansy,sun,num=1;
int main(){
	freopen("matrix.in","r",stdin);
	freopen("matrix.out","w",stdout);
	scanf("%d%d",&n,&k);
	if(k==1){
		printf("1 1");
		return 0;
	}
	else if(k==n*n){
		printf("%d %d",n,n);
		return 0;
	} 
	for(int i=1;i<=n;i++){
		sum+=i;
		if(sum>=k){
			if(i%2==0){
				int x=1,y=i,data=k-(sum-i+1);
				ansx=x+data;
				ansy=y-data;
				printf("%d %d",ansx,ansy);
				return 0;
			}
			else{
				int x=i,y=1,data=k-(sum-i+1);
				ansx=x-data;
				ansy=y+data;
				printf("%d %d",ansx,ansy);
				return 0;
			}
		}	
	}
	if(n%2==0){
		sun=1; num=0;
	}
	for(int i=n-1;i>=1;i--){
		sum+=i;
		if(i%2==0) sun+=2;
		else num+=2;
		if(sum>=k){
			if(i%2==0){
				int x=sun,y=n,data=k-(sum-i+1);
				x+=data;
				y-=data;
				printf("%d %d",x,y);
				return 0;
			}
			else{
				int x=n,y=num,data=k-(sum-i+1);
				x-=data;
				y+=data;
				printf("%d %d",x,y);
				return 0;
			}
		}
	}
	fclose(stdin);
	fclose(stdout);
	return 0;
} 

制作不易,求三连~~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值