(noi.openjudge.cn) 1.8編程基礎之多維數組T01——T10


T01 矩陣交換行

描述

給定一個5*5的矩陣(數學上,一個r×c的矩陣是一個由r行c列元素排列成的矩形陣列),將第n行和第m行交換,輸出交換后的結果。

輸入

輸入共6行,前5行為矩陣的每一行元素,元素與元素之間以一個空格分開。
第6行包含兩個整數m、n,以一個空格分開。(1 <= m,n <= 5)

輸出

輸出交換之后的矩陣,矩陣的每一行元素占一行,元素之間以一個空格分開。

樣例輸入
1 2 2 1 2
5 6 7 8 3
9 3 0 5 3
7 2 1 4 6
3 0 8 2 4
1 5
樣例輸出
3 0 8 2 4
5 6 7 8 3
9 3 0 5 3
7 2 1 4 6
1 2 2 1 2
樣例
 1 #include<iostream>
 2 using namespace std;
 3 int n,m;
 4 int a[6][6];
 5 int main()
 6 {
 7     for(int i=1;i<=5;i++) 
 8       for(int j=1;j<=5;j++) cin>>a[i][j];
 9     cin>>m>>n;
10     for(int i=1;i<=5;i++)
11      if(i==m)
12       {
13           for(int j=1;j<=5;j++) cout<<a[n][j]<<' ';
14           cout<<endl;
15       }
16      else if(i==n) 
17       {
18            for(int j=1;j<=5;j++) cout<<a[m][j]<<' ';
19            cout<<endl;
20       }
21      else 
22       {
23            for(int j=1;j<=5;j++) cout<<a[i][j]<<' ';
24            cout<<endl;
25       }
26       
27 }
View Code

T02 同行列對角線的格子

描述

輸入三個自然數N,i,j (1<=i<=N,1<=j<=N),輸出在一個N*N格的棋盤中(行列均從1開始編號),與格子(i,j)同行、同列、同一對角線的所有格子的位置。

如:n=4,i=2,j=3表示了棋盤中的第二行第三列的格子,如下圖:

第一列

第二列

第三列

第四列

 
       

第一行

   

(2,3)

 

第二行

       

第三行

       

第四行

    

當n=4,i=2,j=3時,輸出的結果是:

(2,1) (2,2) (2,3) (2,4)                        同一行上格子的位置

(1,3) (2,3) (3,3) (4,3)                        同一列上格子的位置

(1,2) (2,3) (3,4)                              左上到右下對角線上的格子的位置

(4,1) (3,2) (2,3) (1,4)                        左下到右上對角線上的格子的位置

輸入

一行,三個自然數N,i,j,相鄰兩個數之間用單個空格隔開。1 <= N <= 10。

輸出

四行:
第一行:從左到右輸出同一行格子位置;
第二行:從上到下輸出同一列格子位置;
第三行:從左上到右下輸出同一對角線格子位置;
第四行:從左下到右上輸出同一對角線格子位置。

其中每個格子位置用如下格式輸出:(x,y),x為行號,y為列號,采用英文標點,中間無空格。
相鄰兩個格子位置之間用單個空格隔開。

樣例輸入

4 2 3
樣例輸出

(2,1) (2,2) (2,3) (2,4)
(1,3) (2,3) (3,3) (4,3)
(1,2) (2,3) (3,4)
(4,1) (3,2) (2,3) (1,4)
樣例

輸出左上到右下的對角線時,注意分x>y和x<y的情況討論

輸出左下到右上的對角線分成兩段,在給定格子左下方的回溯輸出

輸出時用printf格式化輸出比cin更方便

#include<iostream>
#include<cstdio>
using namespace std;
int a[11][11],n,x,y;
void dg(int i,int j)//在給定格子左下方的部分回溯輸出
{
    if(i==n+1||j==0) return;
    dg(i+1,j-1);
    printf("(%d,%d) ",i,j);
}
void dg2(int i,int j)//給定格子右上方的遞歸直接輸出
{
    if(i==0||j==n+1) return;
    printf("(%d,%d) ",i,j);
    dg2(i-1,j+1);
}
int main()
{
    cin>>n>>x>>y;
    for(int i=1;i<=n;i++) 
     printf("(%d,%d) ",x,i);
    cout<<endl;
    for(int i=1;i<=n;i++)
     printf("(%d,%d) ",i,y);
    cout<<endl;
    int c=x-y;
    if(c<=0)//x<y
    {
        for(int i=1;i-c<=n;i++)
         printf("(%d,%d) ",i,i-c);
    }
    else if(c>0)//x>y
    {
        for(int i=1;i+c<=n;i++)
         printf("(%d,%d) ",i+c,i);
    }
    cout<<endl;
    dg(x,y);
    dg2(x-1,y+1);
}
View Code

T03 計算矩陣邊緣元素之和

描述

輸入一個整數矩陣,計算位於矩陣邊緣的元素之和。所謂矩陣邊緣的元素,就是第一行和最后一行的元素以及第一列和最后一列的元素。

輸入

第一行分別為矩陣的行數m和列數n(m < 100,n < 100),兩者之間以一個空格分開。
接下來輸入的m行數據中,每行包含n個整數,整數之間以一個空格分開。

輸出

輸出對應矩陣的邊緣元素和

樣例輸入
3 3
3 4 1
3 7 1
2 0 1
樣例輸出
15
樣例
#include<iostream>
using namespace std;
int s;
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)  
     for(int j=1;j<=m;j++) 
      {
           int x;
           cin>>x;
           if(i==1||i==n||j==1||j==m) s+=x;
      }
    cout<<s;
}
View Code

T04 錯誤探測

描述

給定n*n由0和1組成的矩陣,如果矩陣的每一行和每一列的1的數量都是偶數,則認為符合條件。 
你的任務就是檢測矩陣是否符合條件,或者在僅改變一個矩陣元素的情況下能否符合條件。 
"改變矩陣元素"的操作定義為0變成1或者1變成0。

輸入

輸入n + 1行,第1行為矩陣的大小n(0 < n < 100),以下n行為矩陣的每一行的元素,元素之間以一個空格分開。

輸出

如果矩陣符合條件,則輸出OK;
如果矩陣僅改變一個矩陣元素就能符合條件,則輸出需要改變的元素所在的行號和列號,以一個空格分開。
如果不符合以上兩條,輸出Corrupt。

樣例輸入
樣例輸入1
4
1 0 1 0
0 0 0 0
1 1 1 1
0 1 0 1

樣例輸入2
4
1 0 1 0
0 0 1 0
1 1 1 1
0 1 0 1

樣例輸入3
4
1 0 1 0
0 1 1 0
1 1 1 1
0 1 0 1
樣例輸出
樣例輸出1
OK

樣例輸出2
2 3

樣例輸出3
Corrupt
樣例

因為元素只是0或1,所以統計每一行和每一列的和。

滿足第二條要求,當且僅當行和列各有一個的和是奇數才行。可以先判斷是否滿足這個情況,

如果滿足,輸出記錄下來的第一個行、列為奇數的坐標(如果有多個,那么一定不滿足這個條件,所以只需要記錄第一個)

如果不滿足,則要么行或列有一個的和為奇數,要么和或列至少有一個出現多個和為奇數的情況,這兩種情況都不滿足要求,所以只需要再判斷是否還有和為奇數的行或列即可,有則不符合以上兩條,輸出Corrupt,沒有則輸出OK

 1 #include<iostream>
 2 using namespace std;
 3 int h[101],l[101];
 4 int n;
 5 int x,y,dx,dy;//x統計和為奇數的行的總數,y統計列,dx為第一個出現行為奇數的行號,dy為列號
 6 int main()
 7 {
 8     cin>>n;
 9     for(int i=1;i<=n;i++) 
10       for(int j=1;j<=n;j++) 
11         {
12              int x;
13              cin>>x;
14              h[i]+=x;
15              l[j]+=x;
16         }
17     for(int i=1;i<=n;i++)
18      {
19          if(h[i]&1) x++,dx=i;
20         if(l[i]&1) y++,dy=i;
21      }
22     if(x==1&&y==1) cout<<dx<<' '<<dy;
23     else if(x>0||y>0) cout<<"Corrupt";
24     else cout<<"OK";
25 }
View Code

開始做時有兩個錯誤:

① 在for循環第二個if判斷前加了else,卡了好久

② 輸出判斷的x>1||y>1,忽略了只有一行或者一列為奇數也不滿足條件

T05計算鞍點

描述

給定一個5*5的矩陣,每行只有一個最大值,每列只有一個最小值,尋找這個矩陣的鞍點。
鞍點指的是矩陣中的一個元素,它是所在行的最大值,並且是所在列的最小值。
例如:在下面的例子中(第4行第1列的元素就是鞍點,值為8 )。
11 3 5 6 9
12 4 7 8 10
10 5 6 9 11
8 6 4 7 2
15 10 11 20 25

輸入

輸入包含一個5行5列的矩陣輸出如果存在鞍點,

輸出

鞍點所在的行、列及其值,如果不存在,輸出"not found"

可以證明一個矩陣只存在一個鞍點。

證明:(3*4矩陣為例)

a,b,c,d     

e,f,g,h

j,k,m,n

若e為鞍點,則e為第2行的最大值,第1列的最小值。假設m點另一個鞍點。因為e為鞍點,所以j>e,g<e,所以g<j;因為m為鞍點,所以j<m,g>m,所以j<g,矛盾,所以m不是鞍點,以此類推,可證明矩陣只有一個鞍點

 

樣例輸入
11 3 5 6 9
12 4 7 8 10
10 5 6 9 11
8  6 4 7 2
15 10 11 20 25
樣例輸出
4 1 8
樣例

 

#include<iostream>
using namespace std;
int a[6][6];
bool ok;
int main()
{
    for(int i=1;i<=5;i++)
     for(int j=1;j<=5;j++)
            cin>>a[i][j];
    for(int i=1;i<=5;i++)//枚舉每一行 
     {
          int max_h=-0x7fffffff,k=0;//max_h,當前行的最大值;k,max_h所在列 
          for(int j=1;j<=5;j++)
            if(a[i][j]>max_h)
             {
                 max_h=a[i][j];k=j;
            }
         int min_l=0x7fffffff,q=0;//min_l,第k列的最小值;q,min_l所在行 
         for(int l=1;l<=5;l++)
          if(a[l][k]<min_l) 
          {
                min_l=a[l][k];q=l;
          }
        if(q==i) 
        {
            cout<<i<<' '<<k<<' '<<a[i][k];
            return 0;
        }
     }
    cout<<"not found";
}
View Code

開始賦值最大值時0x7f是錯誤的,0x7f為127,不夠大,int范圍內最大值為0x7fffffff

T06 圖像相似度

描述

給出兩幅相同大小的黑白圖像(用0-1矩陣)表示,求它們的相似度。

 

說明:若兩幅圖像在相同位置上的像素點顏色相同,則稱它們在該位置具有相同的像素點。兩幅圖像的相似度定義為相同像素點數占總像素點數的百分比。

輸入

第一行包含兩個整數m和n,表示圖像的行數和列數,中間用單個空格隔開。1 <= m <= 100, 1 <= n <= 100。
之后m行,每行n個整數0或1,表示第一幅黑白圖像上各像素點的顏色。相鄰兩個數之間用單個空格隔開。
之后m行,每行n個整數0或1,表示第二幅黑白圖像上各像素點的顏色。相鄰兩個數之間用單個空格隔開。

輸出

一個實數,表示相似度(以百分比的形式給出),精確到小數點后兩位。

 

樣例輸入
3 3
1 0 1
0 0 1
1 1 0
1 1 0
0 0 1
0 0 1
樣例輸出
44.44
樣例

 

注意int與double的類型轉換

#include<iostream>
#include<cstdio>
using namespace std;
int m,n,a[101][101],s;
int main()
{
    cin>>m>>n;
    for(int i=1;i<=m;i++)
     for(int j=1;j<=n;j++)
      cin>>a[i][j];
    for(int i=1;i<=m;i++)
     for(int j=1;j<=n;j++)
      {
             int x;
             cin>>x;
             if(x==a[i][j]) s++;
      }
     double k=(double)s/(n*m);
     k*=100;
     printf("%.2lf",k);
} 
View Code

 T07 矩陣歸零消減序列和

描述

給定一個n*n的矩陣(3 <= n <= 100,元素的值都是非負整數)。通過(n-1)次實施下述過程,可把這個矩陣轉換成一個1*1的矩陣。每次的過程如下:

首先對矩陣進行行歸零:即對每一行上的所有元素,都在其原來值的基礎上減去該行上的最小值,保證相減后的值仍然是非負整數,且這一行上至少有一個元素的值為0。

接着對矩陣進行列歸零:即對每一列上的所有元素,都在其原來值的基礎上減去該列上的最小值,保證相減后的值仍然是非負整數,且這一列上至少有一個元素的值為0。

然后對矩陣進行消減:即把n*n矩陣的第二行和第二列刪除,使之轉換為一個(n-1)*(n-1)的矩陣。

下一次過程,對生成的(n-1)*(n-1)矩陣實施上述過程。顯然,經過(n-1)次上述過程, n*n的矩陣會被轉換為一個1*1的矩陣。

請求出每次消減前位於第二行第二列的元素的值。

 

輸入

第一行是一個整數n。
接下來n行,每行有n個正整數,描述了整個矩陣。相鄰兩個整數間用單個空格分隔。

輸出

輸出為n行,每行上的整數為對應矩陣歸零消減過程中,每次消減前位於第二行第二列的元素的值。

樣例輸入
3
1 2 3
2 3 4
3 4 5
樣例輸出
3
0
0
樣例

每次找出每一行的最小值減去,找出每一列的最小值減去,刪除第二行第二列時,for循環一個一個挪過去

本題題意描述有點兒問題,每次消除第二行、第二列,只有n-1個(2,2),所以當行、列等於1時,輸出上一步的(2,2)才能AC

 1 #include<iostream>
 2 using namespace std;
 3 int a[101][101];
 4 int h[101],l[101];
 5 int main()
 6 {
 7     int n; cin>>n;
 8     for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>a[i][j]; 
 9     int s=n;    
10     for(int k=1;k<=s;k++)
11     {
12       cout<<a[2][2]<<endl;
13       for(int i=1;i<=n;i++) h[i]=a[i][1];
14       for(int i=1;i<=n;i++) for(int j=2;j<=n;j++) h[i]=min(h[i],a[i][j]); 
15       for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) a[i][j]-=h[i];
16       for(int i=1;i<=n;i++) l[i]=a[1][i];
17       for(int i=2;i<=n;i++) for(int j=1;j<=n;j++) l[j]=min(l[j],a[i][j]);
18       for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) a[i][j]-=l[j];
19       if(n>2)
20       {
21            for(int i=1;i<=n;i++) for(int j=2;j<n;j++)  a[i][j]=a[i][j+1];
22          for(int i=2;i<n;i++)  for(int j=1;j<=n;j++) a[i][j]=a[i+1][j];
23          n--;
24       }
25     }
26 }
View Code

刪除第二行第二列時,要先判斷n是否大於2,大於才刪,開始時沒注意

刪除第二行第二列時for循環總覺得很麻煩,又想不出其他方法,歡迎各路大神指點

T08 矩陣加法

描述

輸入兩個n行m列的矩陣A和B,輸出它們的和A+B。

輸入

第一行包含兩個整數n和m,表示矩陣的行數和列數。1 <= n <= 100,1 <= m <= 100。
接下來n行,每行m個整數,表示矩陣A的元素。
接下來n行,每行m個整數,表示矩陣B的元素。
相鄰兩個整數之間用單個空格隔開,每個元素均在1~1000之間。

輸出

n行,每行m個整數,表示矩陣加法的結果。相鄰兩個整數之間用單個空格隔開。

樣例輸入
3 3
1 2 3
1 2 3
1 2 3
1 2 3
4 5 6
7 8 9
樣例輸出
2 4 6
5 7 9
8 10 12
樣例

矩陣加法:矩陣A+矩陣B=兩矩陣相同行相同列的元素相加。例:

1,2,3          2,1,3          1+2,2+1,3+3

4,5,6    +    1,1,2    =    4+1,5+1,6+2   

7,8,9          2,0,0          7+2,8+0,9+0

 1 #include<iostream>
 2 using namespace std;
 3 int n,m;
 4 int a[101][101];
 5 int main()
 6 {
 7     cin>>n>>m;
 8     for(int i=1;i<=n;i++)
 9      for(int j=1;j<=m;j++)
10       cin>>a[i][j];
11     for(int i=1;i<=n;i++)
12      for(int j=1;j<=m;j++)
13       {
14            int x;
15            cin>>x;
16            a[i][j]+=x;
17       }
18     for(int i=1;i<=n;i++)
19     {
20         for(int j=1;j<=m;j++)
21          cout<<a[i][j]<<' ';
22         cout<<endl;
23     }
24 }
View Code

T09 矩陣乘法

描述

計算兩個矩陣的乘法。n*m階的矩陣A乘以m*k階的矩陣B得到的矩陣C 是n*k階的,且C[i][j] = A[i][0]*B[0][j] + A[i][1]*B[1][j] + …… +A[i][m-1]*B[m-1][j](C[i][j]表示C矩陣中第i行第j列元素)

輸入

第一行為n, m, k,表示A矩陣是n行m列,B矩陣是m行k列,n, m, k均小於100
然后先后輸入A和B兩個矩陣,A矩陣n行m列,B矩陣m行k列,矩陣中每個元素的絕對值不會大於1000。

輸出

輸出矩陣C,一共n行,每行k個整數,整數之間以一個空格分開。

樣例輸入
3 2 3
1 1
1 1
1 1
1 1 1
1 1 1
樣例輸出
2 2 2
2 2 2
2 2 2
樣例

矩陣乘法:(n*m矩陣A)*(m*k矩陣B)=(n*k矩陣C) 矩陣C中第i行j列的值等於,矩陣A中第i行的值,依次乘矩陣B中第j列的值。例:

1,2           7,8,4           1*7+1*2+2*7+2*2,  1*8+1*1+2*8+2*1, 1*4+1*3+2*4+2*3

3,4    乘    2,1,3   等於   3*7+3*2+4*7+4*2, 3*8+3*1+4*8+4*1, 3*4+3*3+4*4+4*3

5,6                             5*7+5*2+6*7+6*2, 5*8+5*1+6*8+6*1, 5*4+5*3+6*4+6*3

#include<iostream>
using namespace std;
int n,m,k;
int a[101][101],b[101][101],c[101][101];
int main()
{
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++)
     for(int j=1;j<=m;j++)
      cin>>a[i][j];
    for(int i=1;i<=m;i++)
     for(int j=1;j<=k;j++)
      cin>>b[i][j];
    for(int i=1;i<=n;i++)
     for(int j=1;j<=m;j++)
      for(int l=1;l<=k;l++)
    c[i][l]+=a[i][j]*b[j][l];
    for(int i=1;i<=n;i++)
     {
          for(int j=1;j<=k;j++)
           cout<<c[i][j]<<' ';
         cout<<endl;
     }
}
View Code1
#include<iostream>
using namespace std;
int n,m,k;
int a[101][101],b[101][101],c[101][101];
int main()
{
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++)
     for(int j=1;j<=m;j++)
      cin>>a[i][j];
    for(int i=1;i<=m;i++)
     for(int j=1;j<=k;j++)
      cin>>b[i][j];
    for(int i=1;i<=n;i++)
     for(int j=1;j<=k;j++)
      for(int l=1;l<=m;l++)
    c[i][j]+=a[i][l]*b[l][j];
    for(int i=1;i<=n;i++)
     {
          for(int j=1;j<=k;j++)
           cout<<c[i][j]<<' ';
         cout<<endl;
     }
}
View Code2

T10 矩陣轉置

描述

輸入一個n行m列的矩陣A,輸出它的轉置AT

輸入

第一行包含兩個整數n和m,表示矩陣A的行數和列數。1 <= n <= 100,1 <= m <= 100。
接下來n行,每行m個整數,表示矩陣A的元素。相鄰兩個整數之間用單個空格隔開,每個元素均在1~1000之間。

輸出

m行,每行n個整數,為矩陣A的轉置。相鄰兩個整數之間用單個空格隔開。

矩陣轉置即行列交換后輸出。例:

 

樣例輸入
3 3
1 2 3
4 5 6
7 8 9
樣例輸出
1 4 7
2 5 8
3 6 9
樣例
 1 #include<iostream>
 2 using namespace std;
 3 int n,m,a[101][101];
 4 int main()
 5 {
 6     cin>>n>>m;
 7     for(int i=1;i<=n;i++)
 8      for(int j=1;j<=m;j++)
 9       cin>>a[i][j];
10     for(int i=1;i<=m;i++)
11      {
12           for(int j=1;j<=n;j++)
13           cout<<a[j][i]<<' ';
14          cout<<endl; 
15      }
16 } 
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM