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 }
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); }
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; }
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 }
開始做時有兩個錯誤:
① 在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"; }
開始賦值最大值時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); }
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 }
刪除第二行第二列時,要先判斷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 }
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; } }

#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; } }
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 }