CCF 201412-2 Z字形扫描
第一次的思路做错了嘤...
1 #include<iostream>
2 #include<cstring>
3 using namespace std;
4 int arr[505][505];
5 bool visit[505][505];
6 const int dr[] = {0,1,1,-1};//右0,左下1,下2,右上3
7 const int dc[] = {1,-1,0,1};
8 int n;
9 bool inside(int x,int y)
10 {
11 return x>=0 && x<n && y>=0 && y<n;
12 }
13 void solve(int r,int c,int dir,int num)
14 {
15 if(r>0 || c>0) cout<<" ";
16 cout<<arr[r][c];
17 visit[r][c] = false;
18 if(num == n*n) return;
19 if(r == 0 && inside(r+dr[1],c+dc[1]) && visit[r+dr[1]][c+dc[1]])
20 {//在第一行而且存在左下,左下没有读取
21 solve(r+dr[1],c+dc[1],1,num+1);
22 }
23 else if(r == 0 && c!=n-1 && !inside(r+dr[1],c+dc[1]) || r == 0 && c!=n-1 && !visit[r+dr[1]][c+dc[1]])
24 {///在第一行,没有左下或者是左下已经读取,则向右
25 if(inside(r+dr[0],c+dc[0]))
26 solve(r+dr[0],c+dc[0],0,num+1);
27 }
28 else if(c == 0 && r != 0 && visit[r+dr[3]][c+dc[3]]){
29 ///在第一列,右上没有读取,则右上
30 if(inside(r+dr[3],c+dc[3]))
31 solve(r+dr[3],c+dc[3],3,num+1);
32 }
33 else if(c == 0 && r != n-1 && r != 0 && !visit[r+dr[3]][c+dc[3]]){
34 ///在第一列,右上已经读取则向下
35 if(inside(r+dr[2],c+dc[2]))
36 solve(r+dr[2],c+dc[2],2,num+1);
37 }
38 else if(r == n-1 && visit[r+dr[3]][c+dc[3]]) {
39 ///在最后一行,右上没有读取,则右上
40 if(inside(r+dr[3],c+dc[3]))
41 solve(r+dr[3],c+dc[3],3,num+1);
42 }
43 else if(r == n-1 && !visit[r+dr[3]][c+dc[3]]){
44 ///在最后一行,右上已经读取,则向右
45 if(inside(r+dr[0],c+dc[0]))
46 solve(r+dr[0],c+dc[0],0,num+1);
47 }
48 else if(c==n-1 && visit[r+dr[1]][c+dc[1]]){
49 ///在最右一列,如果左下没有读取则向左下
50 if(inside(r+dr[1],c+dc[1]))
51 solve(r+dr[1],c+dc[1],1,num+1);
52 }
53 else if(c==n-1 && !visit[r+dr[1]][c+dc[1]]){
54 ///在最右一列,如果左下已经读取则向下
55 if(inside(r+dr[2],c+dc[2]))
56 solve(r+dr[2],c+dc[2],2,num+1);
57 }else{
58 ///继续相当前方向 前进
59 if(inside(r+dr[dir],c+dc[dir]))
60 solve(r+dr[dir],c+dc[dir],dir,num+1);
61 }
62 }
63
64 int main()
65 {
66 while(cin>>n)
67 {
68 memset(visit,true,sizeof(visit));
69 ///输入
70 for(int i=0;i<n;i++)
71 for(int j=0;j<n;j++)
72 {
73 cin>>arr[i][j];
74 }
75 solve(0,0,0,1);
76 cout<<endl;
77 }
78
79 return 0;
80 }
1 #include<iostream>
2 using namespace std;
3 int arr[505][505];
4 int n;
5 struct node{
6 int x,y;
7 };
8 void show(node c)
9 {
10 cout<<arr[c.x][c.y]<<" ";
11 }
12 bool inside(int x,int y)
13 {
14 return x>=0 && x<n && y>=0 && y<n;
15 }
16 int main()
17 {
18 cin>>n;
19 for(int i=0;i<n;i++)
20 for(int j=0;j<n;j++)
21 {
22 cin>>arr[i][j];
23 }
24 node current = {0,0};
25 show(current);
26 while(true)
27 {
28 if(current.x ==n-1 && current.y == n-1)///到达最后一个结点
29 {
30 break;
31 }
32 ///将每次回到第一行或最后一列,看作一个循环
33 ///1.在第一行或是最后一列,有两种选择,有右边向右,否则向下
34 if(inside(current.x,current.y+1)) {
35 ///可以向右
36 current.y++;
37 show(current);
38 }else{
39 ///不能向右,则向下
40 current.x++;show(current);
41 }
42 ///2.继续向左下
43 while(inside(current.x+1,current.y-1))
44 {
45 current.x++;current.y--;
46 show(current);
47 }
48 ///3.在第一列或是最后一行,如果有下边就向下,否则向右
49 if(inside(current.x+1,current.y)) {
50 ///向下
51 current.x++;show(current);
52 }else{
53 ///向右
54 current.y++;show(current);
55 }
56 ///4.向右上
57 while(inside(current.x-1,current.y+1)){
58 current.x--;current.y++;
59 show(current);
60 }
61 }
62
63 return 0;
64 }
来源:oschina
链接:https://my.oschina.net/u/4408350/blog/4244951