#138-(EZOI模拟赛)【数学技巧】旋转矩阵

Description

一个n行n列的螺旋矩阵可由如下方法生成:

从矩阵的左上角(第1行第1列)出发,初始时向右移动;如果前方是未曾经过的格子,则继续前进,否则右转;重复上述操作直至经过矩阵中所有格子。根据经过顺序,在格子中依次填入1, 2, 3, ... , n,便构成了一个螺旋矩阵。

下图是一个n = 4 时的螺旋矩阵。

1 2 3 4

12 13 14 5

11 16 15 6

10 9 8 7

现给出矩阵大小n以及i和j,请你求出该矩阵中第i行第j列的数是多少。

Input

共一行,包含三个整数 n,i,j,每两个整数之间用一个空格隔开,分别表示矩阵大小、待求的数所在的行号和列号。

Output

一个整数,表示相应矩阵中第i行第j列的数。

Sample Input

4 2 3

Sample Output

14

HINT

 

【数据说明】

对于50%的数据,1≤n≤100;

对于100%的数据,1 ≤ n ≤ 30,000,    1 ≤ i ≤ n,   1 ≤ j ≤ n。

先得到该数在第几圈,然后在这一圈暴力找。

#include 
#include 

#define SIZE 30010

using namespace std;

int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};

int main(void)
{
	int n, ex, ey, x = 1, y = 1, r, c, dis = 1, d = 0, uplimit, downlimit, k, temp = 1;
	
	scanf("%d%d%d", &n, &ex, &ey);
	
	k = min(min(ex, ey), min(n - ex, n - ey) + 1); // 在第几圈
	uplimit = k; // 上限
	downlimit = n - k + 1; // 下线
	while (--k)
	{
		temp -= 2;
		dis += (n + temp) << 2;
	}
	if ((ex == uplimit) && (ey == uplimit))
	{
		printf("%d", dis);
		return 0;
	}
	x = y = uplimit;
	for ( ; ; ) // 暴力找
	{
		++dis;
		r = x + dx[d];
		c = y + dy[d];
		if (((r < uplimit) || (r > downlimit)) || ((c < uplimit) || (c > downlimit))) // 需要换方向
		{
			++d;
			d %= 4;
			r = x + dx[d];
			c = y + dy[d];
		}
		if ((r == ex) && (c == ey)) // 找到结果
		{
			printf("%d", dis);
			return 0;
		}
		x = r;
		y = c;
	}
	
	return 0;
}

 

你可能感兴趣的:(刷题,gdgzoi刷题)