T01 矩陣交換行

描述

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

輸入

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

輸出

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

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

樣例

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

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為列號,採用英文標點,中間無空格。
相鄰兩個格子位置之間用單個空格隔開。

  1. 樣例輸入
  2.  
  3. 樣例輸出
  4.  
  5. (,) (,) (,) (,)
  6. (,) (,) (,) (,)
  7. (,) (,) (,)
  8. (,) (,) (,) (,)

樣例

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

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

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

  1. #include<iostream>
  2. #include<cstdio>
  3. using namespace std;
  4. int a[][],n,x,y;
  5. void dg(int i,int j)//在給定格子左下方的部分回溯輸出
  6. {
  7. if(i==n+||j==) return;
  8. dg(i+,j-);
  9. printf("(%d,%d) ",i,j);
  10. }
  11. void dg2(int i,int j)//給定格子右上方的遞迴直接輸出
  12. {
  13. if(i==||j==n+) return;
  14. printf("(%d,%d) ",i,j);
  15. dg2(i-,j+);
  16. }
  17. int main()
  18. {
  19. cin>>n>>x>>y;
  20. for(int i=;i<=n;i++)
  21. printf("(%d,%d) ",x,i);
  22. cout<<endl;
  23. for(int i=;i<=n;i++)
  24. printf("(%d,%d) ",i,y);
  25. cout<<endl;
  26. int c=x-y;
  27. if(c<=)//x<y
  28. {
  29. for(int i=;i-c<=n;i++)
  30. printf("(%d,%d) ",i,i-c);
  31. }
  32. else if(c>)//x>y
  33. {
  34. for(int i=;i+c<=n;i++)
  35. printf("(%d,%d) ",i+c,i);
  36. }
  37. cout<<endl;
  38. dg(x,y);
  39. dg2(x-,y+);
  40. }

T03 計算矩陣邊緣元素之和

描述

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

輸入

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

輸出

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

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

樣例

  1. #include<iostream>
  2. using namespace std;
  3. int s;
  4. int main()
  5. {
  6. int n,m;
  7. cin>>n>>m;
  8. for(int i=;i<=n;i++)
  9. for(int j=;j<=m;j++)
  10. {
  11. int x;
  12. cin>>x;
  13. if(i==||i==n||j==||j==m) s+=x;
  14. }
  15. cout<<s;
  16. }

T04 錯誤探測

描述

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


輸入

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

輸出

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

  1. 樣例輸入
  2. 樣例輸入1
  3.  
  4. 樣例輸入2
  5.  
  6. 樣例輸入3
  7.  
  8. 樣例輸出
  9. 樣例輸出1
  10. OK
  11.  
  12. 樣例輸出2
  13.  
  14. 樣例輸出3
  15. Corrupt

樣例

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

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

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

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

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

開始做時有兩個錯誤:

① 在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不是鞍點,以此類推,可證明矩陣只有一個鞍點

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

樣例

  1. #include<iostream>
  2. using namespace std;
  3. int a[][];
  4. bool ok;
  5. int main()
  6. {
  7. for(int i=;i<=;i++)
  8. for(int j=;j<=;j++)
  9. cin>>a[i][j];
  10. for(int i=;i<=;i++)//列舉每一行
  11. {
  12. int max_h=-0x7fffffff,k=;//max_h,當前行的最大值;k,max_h所在列
  13. for(int j=;j<=;j++)
  14. if(a[i][j]>max_h)
  15. {
  16. max_h=a[i][j];k=j;
  17. }
  18. int min_l=0x7fffffff,q=;//min_l,第k列的最小值;q,min_l所在行
  19. for(int l=;l<=;l++)
  20. if(a[l][k]<min_l)
  21. {
  22. min_l=a[l][k];q=l;
  23. }
  24. if(q==i)
  25. {
  26. cout<<i<<' '<<k<<' '<<a[i][k];
  27. return ;
  28. }
  29. }
  30. cout<<"not found";
  31. }

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

T06 影象相似度

描述

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

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

輸入

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

輸出

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

  1. 樣例輸入
  2.  
  3. 樣例輸出
  4. 44.44

樣例

注意int與double的型別轉換

  1. #include<iostream>
  2. #include<cstdio>
  3. using namespace std;
  4. int m,n,a[][],s;
  5. int main()
  6. {
  7. cin>>m>>n;
  8. for(int i=;i<=m;i++)
  9. for(int j=;j<=n;j++)
  10. cin>>a[i][j];
  11. for(int i=;i<=m;i++)
  12. for(int j=;j<=n;j++)
  13. {
  14. int x;
  15. cin>>x;
  16. if(x==a[i][j]) s++;
  17. }
  18. double k=(double)s/(n*m);
  19. k*=;
  20. printf("%.2lf",k);
  21. }

 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行,每行上的整數為對應矩陣歸零消減過程中,每次消減前位於第二行第二列的元素的值。

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

樣例

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

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

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

刪除第二行第二列時,要先判斷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個整數,表示矩陣加法的結果。相鄰兩個整數之間用單個空格隔開。

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

樣例

矩陣加法:矩陣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[][];
  5. int main()
  6. {
  7. cin>>n>>m;
  8. for(int i=;i<=n;i++)
  9. for(int j=;j<=m;j++)
  10. cin>>a[i][j];
  11. for(int i=;i<=n;i++)
  12. for(int j=;j<=m;j++)
  13. {
  14. int x;
  15. cin>>x;
  16. a[i][j]+=x;
  17. }
  18. for(int i=;i<=n;i++)
  19. {
  20. for(int j=;j<=m;j++)
  21. cout<<a[i][j]<<' ';
  22. cout<<endl;
  23. }
  24. }

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個整數,整數之間以一個空格分開。

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

樣例

矩陣乘法:(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

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

1

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

2

T10 矩陣轉置

描述

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

輸入

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

輸出

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

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

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

樣例

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