俊介三

一天更新一点,一天积累一点

导航

顺时针打印矩阵

Posted on 2013-04-03 22:09  俊介三在前进  阅读(149)  评论(0)    收藏  举报

题目描述:
    输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵:
    1 2 3 4
    5 6 7 8
    9 10 11 12
    13 14 15 16
    则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10

思路:直接模拟它进行顺时针的行走,若遇到矩阵范围外,或已走过的区域,则转向;若不能转向了,则结束。
但奇怪的是超时?最后一个case还没跑1秒就过去了~
http://ac.jobdu.com/problem.php?cid=1039&pid=7

代码:

#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;

int arr[1005][1005];
bool used[1005][10005];
int main(){
    int m,n;
    int i,j;
    while(scanf("%d %d",&m,&n)!=EOF){
        memset(used,false,sizeof(used));
        for(i=0;i<m;i++)
            for(j=0;j<n;j++)
                scanf("%d",&arr[i][j]);
        
        i=0;
        j=-1;

        //0->left 1->down 2->right 3->up
        int mode = 0;
        
        while(1){
            if(mode==0){
                j++;
                while(j<n && !used[i][j]){
                    printf("%d ",arr[i][j]);
                    used[i][j]=true;
                    j++;
                }
                j--;
                if(i+1>=m || used[i+1][j]) break;
            }
            if(mode==1){
                i++;
                while(i<m && !used[i][j]){
                    printf("%d ",arr[i][j]);
                    used[i][j]=true;
                    i++;
                }
                i--;
                if(j-1<0 || used[i][j-1]) break;
            }
            if(mode==2){
                j--;
                while(j>=0 && !used[i][j]){
                    printf("%d ",arr[i][j]);
                    used[i][j]=true;
                    j--;
                }
                j++;
                if(i-1<0 || used[i-1][j]) break;
            }
            if(mode==3){
                i--;
                while(i>=0 && !used[i][j]){
                    printf("%d ",arr[i][j]);
                    used[i][j]=true;
                    i--;
                }
                i++;
                if(j+1>=n || used[i][j+1]) break;
            }
            mode = (mode+1)%4;
        }
        puts("");
    }
    return 0;
}

 

update(2013.4.16):稍微优化一下就过了。
优化地方如程序中的注释:

#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;

int arr[1005][1005];
bool used[1005][10005];
int main(){
    int m,n;
    int i,j;
    while(scanf("%d %d",&m,&n)!=EOF){
        //memset(used,false,sizeof(used));
        for(i=0;i<m;i++)
            for(j=0;j<n;j++){
                scanf("%d",&arr[i][j]);
                used[i][j] = false;
            }
        
        i=0;
        j=-1;

        //0->left 1->down 2->right 3->up
        int mode = 0;
        
        int TOTAL = m*n;   //事先计算好这一个,防止后来重复算
        int count = 0;
        while(1){
            if(mode==0){
                j++;
                while(j<n && !used[i][j]){
                    printf("%d ",arr[i][j]);
                    count++;
                    used[i][j]=true;
                    j++;
                }
                j--;
            }else if(mode==1){     //换成else if 比每个都用if比较好
                i++;
                while(i<m && !used[i][j]){
                    printf("%d ",arr[i][j]);
                    count++;
                    used[i][j]=true;
                    i++;
                }
                i--;
            }else if(mode==2){
                j--;
                while(j>=0 && !used[i][j]){
                    printf("%d ",arr[i][j]);
                    count++;
                    used[i][j]=true;
                    j--;
                }
                j++;
            }else{
                i--;
                while(i>=0 && !used[i][j]){
                    printf("%d ",arr[i][j]);
                    count++;
                    used[i][j]=true;
                    i--;
                }
                i++;
            }
            
            if(count == TOTAL) break;  //统计已经打印的个数,再最后判断而不需要以上每种情况都判断
            mode = (mode+1)%4;
        }
        puts("");
    }
    return 0;
}