Trang 1 trên tổng số 2 12 Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 19 kết quả

Đề tài: Tìm Ma trận ziczac với cấp bất kỳ

  1. #1
    No Avatar
    truongloc_phuc Khách

    Wink Tìm Ma trận ziczac với cấp bất kỳ

    Anh em giúp dùm bài này: Nhập vào số N, chạy vòng for để in ra hình vuông cạnh N chạy từ 1 đến N*N theo đường ziczac.
    VD: N=4

    1 3 6 10
    2 5 9 13
    4 8 12 15
    7 11 14 16
    Đã được chỉnh sửa lần cuối bởi peterdrew : 31-07-2010 lúc 11:31 PM.

  2. #2
    Ngày gia nhập
    01 2010
    Nơi ở
    до свидания!
    Bài viết
    1,766

    Cái này chắc gần giống ý của cậu: hướng dẫn em giải bài ma trận zic zac.
    hoặc: sắp xếp ma trận theo hình zic zắc

    Chỉ sắp xếp lại với ý tưởng của cậu là OK ngay đó!

  3. #3
    Ngày gia nhập
    01 2010
    Nơi ở
    до свидания!
    Bài viết
    1,766

    Sau khi nghiên cứu kỹ lưỡng yêu cầu của cậu, kết hợp với suy luận toán học, tối này Peter quyết định thức khuya để làm đề tài này (Thú thực là hơi khó chịu vì hôm đó chưa tìm ra kết quả, suy nghĩ từ hôm đó đấy... Hì):

    1. Phân tích thuật giải:
    Đặt một hệ trục toạ độ Oxy với các trục Ox là phương ngang có chiều từ trái qua phải, Oy là phương thẳng đứng có chiều từ trên xuống dưới; gốc toạ độ O là điểm Trái-Trên cùng của ma trận! Gốc toạ độ này tương ứng với giá trị 1.
    Giả sử ta cần xác định toạ độ điểm M(i,j); chúng ta xét các trường hợp: (Dĩ nhiên i,j luôn không vượt quá n-1)
    * i+j nằm trong đoạn [0,k-1], lúc này thì dựa vào đường thẳng y=0 chúng ta suy ra các tương quan về các điểm M(i,0) có giá trị nằm trong dãy số U[0]=1, U[i]=U[i-1]+i+1; Và dễ suy được U[i]=(i+1)*(i+2)/2, đây là các giá trị của M(i,0); từ đó suy ra các điểm khác M(i,j) có giá trị là
    PHP Code:
    (i+j+1)*(i+j+2)/
    .

    * i+j nằm trong đoạn [n,2*n-2], với cách làm tương tự như trên ứng với đường thẳng y=n-1 ta có công thức chung tổng quát cho M(i,j) như sau:
    PHP Code:
    n*n+n-(2*n-i-j-1)*(2*n-i-j)/2-j
    Vậy ta đã hoàn thành việc xác định một phần tử của ma trận Ziczac trên thông qua vị trí hàng, cột và cấp của ma trận! Sau đây chúng ta đi vào code:

    2. Chương trình chính:

    Đây là chương trình mà Peter viết vẫn chưa đầy đủ cách trình bày, mong các bạn trình bày cho tốt (Vì với cấp càng lớn thì số chữ số của phần tử tăng lên, làm dịch vị trí các phần tử đi trông rất xấu....):
    PHP Code:
    #include<stdio.h>
    #include<conio.h>

    int main()
    {
        
    unsigned n,i,j,a[100][100];
        
    printf("Nhap cap cua ma tran, n= ");
        
    scanf("%d",&n);
        
    printf("\nMa tran Ziczac cap %d nhu sau: \n",n);
        for (
    i=0;i<n;i++)
            for (
    j=0;j<n;j++)
            {
                if ((
    i+j>=0)&&(i+j<=n-1))
                    
    a[i][j]=(i+j+1)*(i+j+2)/2-i;
                else
                    
    a[i][j]=n*n+n-(2*n-i-j-1)*(2*n-i-j)/2-i;
            }
            for (
    i=0;i<n;i++)
            {
                
    printf("\n");
                for (
    j=0;j<n;j++)
                    
    printf("%d    ",a[i][j]);
            }
            
    getch();
            return 
    0;


    3. Lời kết:


    Đây là bài toán rất hay khiến Peter trằn trọc, suy nghĩ. Hy vọng bạn nào cần thì lấy về dùng, trong các bài toán thì Peter thích nhất bài này đó (Nghĩ mấy ngày liền, hì hì).

  4. #4
    Ngày gia nhập
    12 2009
    Bài viết
    190

    Cách của anh peter tính ra công thức nhìn gớm quá.
    Ta nhận thấy là các số được điền theo các đường chéo từ dưới lên. Tổng cộng là có 2n - 1 đường. n đường đầu ( 0 -> n - 1 ) giống nhau và n - 1 đường còn lại giống nhau ( n + 1 -> 2n - 1 )
    C Code:
    1. #include <stdio.h>
    2.  
    3. #define max 50
    4.  
    5. void zigzak( int arr[][ max ], int nArr )
    6. {
    7.     int row;        // row
    8.     int col;        // column
    9.     int dia;        // diagonal
    10.     int count = 1;
    11.  
    12.     // Cac duong cheo tu 0 den n - 1
    13.     for( dia = 0; dia < nArr; dia++ )
    14.     {
    15.         for( row = dia, col = 0; row >= 0; row--, col++ )
    16.         {
    17.             arr[ row ][ col ] = count++;
    18.         }
    19.     }
    20.  
    21.     // Cac duong cheo tu n + 1 den 2n - 1
    22.     for( dia = 1; dia < nArr; dia++ )
    23.     {
    24.         for( row = nArr - 1, col = dia; col < nArr; row--, col++ )
    25.         {
    26.             arr[ row ][ col ] = count++;
    27.         }
    28.     }
    29. }
    30.  
    31. int main()
    32. {
    33.     int square[ max ][ max ];
    34.     int size = 10;
    35.     int i, j;
    36.  
    37.     zigzak( square, size );
    38.  
    39.     for( i = 0; i < size; i++ )
    40.     {
    41.         for( j = 0; j < size; j++ )
    42.             printf( "%4d", square[ i ][ j ] );
    43.         printf( "\n\n" );
    44.     }
    45.  
    46.     return 0;
    47. }

  5. #5
    Ngày gia nhập
    01 2010
    Nơi ở
    до свидания!
    Bài viết
    1,766

    Trích dẫn Nguyên bản được gửi bởi pannaruto Xem bài viết
    Cách của anh peter tính ra công thức nhìn gớm quá.
    Ta nhận thấy là các số được điền theo các đường chéo từ dưới lên. Tổng cộng là có 2n - 1 đường. n đường đầu ( 0 -> n - 1 ) giống nhau và n - 1 đường còn lại giống nhau ( n + 1 -> 2n - 1 )
    C Code:
    1. #include <stdio.h>
    2.  
    3. #define max 50
    4.  
    5. void zigzak( int arr[][ max ], int nArr )
    6. {
    7.     int row;        // row
    8.     int col;        // column
    9.     int dia;        // diagonal
    10.     int count = 1;
    11.  
    12.     // Cac duong cheo tu 0 den n - 1
    13.     for( dia = 0; dia < nArr; dia++ )
    14.     {
    15.         for( row = dia, col = 0; row >= 0; row--, col++ )
    16.         {
    17.             arr[ row ][ col ] = count++;
    18.         }
    19.     }
    20.  
    21.     // Cac duong cheo tu n + 1 den 2n - 1
    22.     for( dia = 1; dia < nArr; dia++ )
    23.     {
    24.         for( row = nArr - 1, col = dia; col < nArr; row--, col++ )
    25.         {
    26.             arr[ row ][ col ] = count++;
    27.         }
    28.     }
    29. }
    30.  
    31. int main()
    32. {
    33.     int square[ max ][ max ];
    34.     int size = 10;
    35.     int i, j;
    36.  
    37.     zigzak( square, size );
    38.  
    39.     for( i = 0; i < size; i++ )
    40.     {
    41.         for( j = 0; j < size; j++ )
    42.             printf( "%4d", square[ i ][ j ] );
    43.         printf( "\n\n" );
    44.     }
    45.  
    46.     return 0;
    47. }
    Cũng hay đấy nhỉ??? Vậy mà nghĩ không ra cái kiểu này,....Dẫu gì thì nó cũng là công sức mình tìm tòi đó mà, hì hì. Cảm ơn Pannaruto vì câu trả bài quá cừ, OK.

  6. #6
    Ngày gia nhập
    07 2010
    Nơi ở
    Thư viện
    Bài viết
    123

    Mặc định Tìm Ma trận ziczac với cấp bất kỳ

    Code:
    void ziczac(int a[][50],int n)
    {
    	int i,s=1,h=0,dem=0;
    	while(s<=n*n)
    	{
    		for(i=0;i<=dem;i++)
    			if(h<n)
    				a[h-i][i]=s++;
    			else
    				a[n-1-i][h-n+i+1]=s++;
    		h++;
    		if(h<n)
    			dem++;
    		else
    			dem--;
    	}
    }
    "một người chưa bao giờ vấp ngã, chưa bao giờ thất bại, chưa bao giờ phạm phải bất kỳ một sai lầm nào là một người có tương lai vô cùng mờ mịt." - Og Mandino

    Tổng hợp các quyển sách hay Mp3

  7. #7
    Ngày gia nhập
    01 2010
    Nơi ở
    до свидания!
    Bài viết
    1,766

    Trích dẫn Nguyên bản được gửi bởi dkbcnncb11 Xem bài viết
    Code:
    void ziczac(int a[][50],int n)
    {
    	int i,s=1,h=0,dem=0;
    	while(s<=n*n)
    	{
    		for(i=0;i<=dem;i++)
    			if(h<n)
    				a[h-i][i]=s++;
    			else
    				a[n-1-i][h-n+i+1]=s++;
    		h++;
    		if(h<n)
    			dem++;
    		else
    			dem--;
    	}
    }
    Hãy demo rõ ràng nào cậu, Peter thấy có vẻ ngắn gọn hơn chút rồi đấy,....

  8. #8
    Ngày gia nhập
    07 2010
    Nơi ở
    Thư viện
    Bài viết
    123

    Trích dẫn Nguyên bản được gửi bởi peterdrew Xem bài viết
    Hãy demo rõ ràng nào cậu, Peter thấy có vẻ ngắn gọn hơn chút rồi đấy,....
    Bây giờ em chưa rãnh để tối em demo .
    "một người chưa bao giờ vấp ngã, chưa bao giờ thất bại, chưa bao giờ phạm phải bất kỳ một sai lầm nào là một người có tương lai vô cùng mờ mịt." - Og Mandino

    Tổng hợp các quyển sách hay Mp3

  9. #9
    Ngày gia nhập
    01 2010
    Nơi ở
    до свидания!
    Bài viết
    1,766

    Trích dẫn Nguyên bản được gửi bởi dkbcnncb11 Xem bài viết
    Bây giờ em chưa rãnh để tối em demo .
    Vậy cũng được, chờ cái xem; Peter rất thích bài toán này nên muốn các bạn tiếp tục góp ý (nếu quan trọng hơn nữa thì nó sẽ được stick trong box để mọi người cùng tham khảo). Cảm ơn dkbcnncb11,...

    p/s: Mới đây Peter thường thấy được nhiều code hay từ cậu, hy vọng cậu vẫn hăng say với diễn đàn.

  10. #10
    Ngày gia nhập
    07 2010
    Nơi ở
    Thư viện
    Bài viết
    123

    @peter : cám ơn anh peter lần đầu tiên được khen.
    tự nhiên thây đổi 180 độ bất ngờ quá ^^!.

    còn đây là demon :

    00 01 02 03
    10 11 12 13
    20 21 22 23
    30 31 32 33

    đường chéo có j+i bằng nhau
    vd: đường chéo a[1][0] với a[0][1]; a[2][0] với a[1][1] và a[0][2]...

    và mỗi lần tăng 1 đường chéo thì tăng lên 1 đơn vị. đặt h = số đường chéo.

    ta cho i=h , j=0 và cho i trừ dần qua j
    vd: a[3][0] -> a[2][1] -> a[1][2] -> a[0][3];

    với thuật toán đó ta tính được hình tam giác chiều cao n;
    phần còn lại ta thấy nó đối xứng với hình trên thì ta làm ngược lại với thuật toán trên
    vd:
    1 3 6 10
    2 5 9 -
    4 8 - -
    7 - - -

    ta chạy từ dem++ ngược lại thì dem-- và
    a[n-1][h-(n-1)] -> a[n-1-dem][h-(n-1)+dem];
    "một người chưa bao giờ vấp ngã, chưa bao giờ thất bại, chưa bao giờ phạm phải bất kỳ một sai lầm nào là một người có tương lai vô cùng mờ mịt." - Og Mandino

    Tổng hợp các quyển sách hay Mp3

Các đề tài tương tự

  1. Code sắp xếp các phần tử trong mảng tăng dần theo đường ziczac chéo
    Gửi bởi memorypc trong diễn đàn Thủ thuật, Tutorials và Mã nguồn C/C++/C++0x
    Trả lời: 0
    Bài viết cuối: 07-04-2008, 11:40 AM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn