演算法競賽_蛇形填數_C++
阿新 • • 發佈:2019-02-08
描述
在n*n方陳裡填入1,2,…,n*n,要求填成蛇形。例如n=4時方陳為:
10 11 12 1
9 16 13 2
8 15 14 3
7 6 5 4
輸入
直接輸入方陳的維數,即n的值。(n<=100)
輸出
輸出結果是蛇形方陳。
樣例輸入
3
樣例輸出
7 8 1
6 9 2
5 4 3
方法一、用於訓練列舉型別的使用。
宣告列舉型別以enum開頭。
說明:
(1)列舉型別按常量處理,故稱列舉常量,不接受賦值,故其元素值是固定的。
(2)列舉元素作為常量,它們是有值的,其值是一個整數,編譯系統按定義時的順序將他們賦值為0,1,2,3,…
(3)列舉值可以用來做判斷比較,按整數規則進行比較。
(4)不能把一個整數直接賦值給一個列舉變數,列舉變數只接受列舉型別資料,如curDir = DOWN, 而curDir=1則是錯誤的!!應先進行強制型別轉換才能賦值,如:
curDir=(DIR)1; //C語言風格
curDir=DIR(1); //C++風格
#include <stdio.h>
#include <stdlib.h>
//#include <windows.h>
//這裡直接用int替代Point結構體就行
typedef struct _point{
int rn;
} Point;
//方向迴圈
enum DIR
{
DOWN,LEFT,UP,RIGHT
};
int main()
{
int n, i, r, c, nr, nc;
DIR curDir = DOWN;
Point* curPoint;
scanf ("%d", &n);
Point* points = (Point*)malloc(sizeof(Point) * n * n); //開闢新空間,值隨機。
for(i=0;i<n*n;i++){
//curPoint = &points[i];
//curPoint->rn = 0;
//(points+i)->rn = 0;
points[i].rn =0;
} //數值清理,保證轉向預測的判斷。
nr = r = 0;
nc = c = n - 1;
for(i = 0 ; i < n * n; i++)
{
curPoint = &points[r*n + c];
curPoint->rn = i + 1;
//預測下一個點
switch(curDir)
{
case DOWN:
nr = r + 1;
break;
case UP:
nr = r - 1;
break;
case LEFT:
nc = c - 1;
break;
case RIGHT:
nc = c + 1;
break;
default:
break;
}
//碰到邊界和已經填過的 就改變方向
if(nr < 0 || nr >= n || nc < 0 || nc >= n || points[nr*n + nc].rn > 0)
{
curDir = (DIR)((int)curDir + 1);
if((int)curDir >= 4)
curDir = (DIR)0;
nr = r;
nc = c;
}
//根據改變的方向確定下一個位置
switch(curDir)
{
case DOWN:
r++;
break;
case UP:
r--;
break;
case LEFT:
c--;
break;
case RIGHT:
c++;
break;
default:
break;
}
}
//輸出
for(i = 0; i < n * n; i++)
{
curPoint = &points[i];
printf("%3d ", curPoint->rn);
if((i+1) % n == 0)
printf("\n");
}
free(points);
return 0;
}
法二
說明:當maxN很大時,建議設定為全域性變數,若主函式內定義,容易造成程式異常崩潰。–《演算法競賽入門經典》
#include <bits/stdc++.h>
#define maxN 10
using namespace std;
int a[maxN][maxN];
int main(){
int n,x,y,total=0;
cin >> n;
memset(a,0,sizeof(a));
total = a[x=0][y=n-1] = 1;
while(total<n*n){
while(x+1<n && !a[x+1][y]) a[++x][y] = ++total;
while(y-1>=0 && !a[x][y-1]) a[x][--y]= ++total;
while(x-1>=0 && !a[x-1][y]) a[--x][y]= ++total;
while(y+1<n && !a[x][y+1]) a[x][++y] = ++total;
}
for(x=0;x<n;x++){
for(y=0;y<n; y++)
cout << a[x][y];
cout << endl;
}
return 0;
}
法三、該演算法主要考慮到最後一個元素的位置。
#include<stdio.h>
int main()
{
int a,b,c,d,n,sum=1;
int yi[101][101];
scanf("%d",&n);
for(a=0;a<=(n-1)/2;a++)
{
for(b=a;b<=n-a-1;b++)
yi[b][n-a-1]=sum++;
for(b=n-2-a;b>=a;b--)
yi[n-a-1][b]=sum++;
for(b=n-a-2;b>=a;b--)
yi[b][a]=sum++;
for(b=a+1;b<n-a-1;b++)
yi[a][b]=sum++;
}
for(c=0;c<n;c++)
{
for(d=0;d<n;d++)
printf("%d ",yi[c][d]);
printf("\n");
}
}