1. 程式人生 > >NOIP 2014 普及組 T3 螺旋矩陣

NOIP 2014 普及組 T3 螺旋矩陣

【題意】

已知:n,r,c(n<=30000)

條件:給定n行n列的螺旋矩陣(從矩陣的左上角(1,1)出發,初始時向右移動;如果前方是未曾經過的格子, 則繼續前進,否則右轉;重複上述操作直至經過矩陣中所有格子。根據經過順序,在格子中依次填入 1, 2, 3, ... , n^2)

/*

如下圖是一個 n = 4 時的螺旋矩陣:

 1       2       3      4

12     13     14     5

11     16     15     6

10      9       8      7

求:n階螺旋矩陣第r行第c列的值

【構思】

最常見的方法就是直接構造,時間複雜度O(n^2),在本題會超時;

那麼就要化簡運算:發現每層有4個轉彎點,可以按轉彎點轉移,若(r,c)在其中則直接輸出答案。

這樣每層就只有4個點,時間複雜度為O(n)

【實現】

#include <cstdio>
#include <cstring>
#include <cstdlib>

using namespace std;

int cnt,n,x,y,rx,ry;

int main(void)
{
	freopen("test.in","r",stdin);
	scanf("%d%d%d",&n,&rx,&ry);
	for (int i=n-1;;i-=2)
	{
		x++,y++;
		if (x==rx&&y<=ry&&ry<=y+n-1)
		{
			printf("%d\n",cnt+ry-y+1);
			break;
		}
		cnt+=i;
		y+=i;
		if (y==ry&&x<=rx&&rx<=x+n-1)
		{
			printf("%d\n",cnt+rx-x+1);
			break;
		}
		cnt+=i;
		x+=i;
		if (x==rx&&ry<=y&&y-n+1<=ry)
		{
			printf("%d\n",cnt+y-ry+1);
			break;
		}
		cnt+=i;
		y-=i;
		if (y==ry&&rx<=x&&x-n+1<=rx)
		{
			printf("%d\n",cnt+x-rx+1);
			break;
		}
		cnt+=i;
		x-=i;
	}
	return 0;
}

【回顧】

1、構造類問題的解決方法    ①模擬   ②按照特殊點轉移

2、構造類問題關鍵在於找出層次和特殊點