T01 矩陣交換行
描述
給定一個5*5的矩陣(數學上,一個r×c的矩陣是一個由r行c列元素排列成的矩形陣列),將第n行和第m行交換,輸出交換後的結果。
輸入
輸入共6行,前5行為矩陣的每一行元素,元素與元素之間以一個空格分開。
第6行包含兩個整數m、n,以一個空格分開。(1 <= m,n <= 5)
輸出
輸出交換之後的矩陣,矩陣的每一行元素佔一行,元素之間以一個空格分開。
- 樣例輸入
- 樣例輸出
樣例
- #include<iostream>
- using namespace std;
- int n,m;
- int a[][];
- int main()
- {
- for(int i=;i<=;i++)
- for(int j=;j<=;j++) cin>>a[i][j];
- cin>>m>>n;
- for(int i=;i<=;i++)
- if(i==m)
- {
- for(int j=;j<=;j++) cout<<a[n][j]<<' ';
- cout<<endl;
- }
- else if(i==n)
- {
- for(int j=;j<=;j++) cout<<a[m][j]<<' ';
- cout<<endl;
- }
- else
- {
- for(int j=;j<=;j++) cout<<a[i][j]<<' ';
- cout<<endl;
- }
- }
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為列號,採用英文標點,中間無空格。
相鄰兩個格子位置之間用單個空格隔開。
- 樣例輸入
- 樣例輸出
- (,) (,) (,) (,)
- (,) (,) (,) (,)
- (,) (,) (,)
- (,) (,) (,) (,)
樣例
輸出左上到右下的對角線時,注意分x>y和x<y的情況討論
輸出左下到右上的對角線分成兩段,在給定格子左下方的回溯輸出
輸出時用printf格式化輸出比cin更方便
- #include<iostream>
- #include<cstdio>
- using namespace std;
- int a[][],n,x,y;
- void dg(int i,int j)//在給定格子左下方的部分回溯輸出
- {
- if(i==n+||j==) return;
- dg(i+,j-);
- printf("(%d,%d) ",i,j);
- }
- void dg2(int i,int j)//給定格子右上方的遞迴直接輸出
- {
- if(i==||j==n+) return;
- printf("(%d,%d) ",i,j);
- dg2(i-,j+);
- }
- int main()
- {
- cin>>n>>x>>y;
- for(int i=;i<=n;i++)
- printf("(%d,%d) ",x,i);
- cout<<endl;
- for(int i=;i<=n;i++)
- printf("(%d,%d) ",i,y);
- cout<<endl;
- int c=x-y;
- if(c<=)//x<y
- {
- for(int i=;i-c<=n;i++)
- printf("(%d,%d) ",i,i-c);
- }
- else if(c>)//x>y
- {
- for(int i=;i+c<=n;i++)
- printf("(%d,%d) ",i+c,i);
- }
- cout<<endl;
- dg(x,y);
- dg2(x-,y+);
- }
T03 計算矩陣邊緣元素之和
描述
-
輸入一個整數矩陣,計算位於矩陣邊緣的元素之和。所謂矩陣邊緣的元素,就是第一行和最後一行的元素以及第一列和最後一列的元素。
輸入
第一行分別為矩陣的行數m和列數n(m < 100,n < 100),兩者之間以一個空格分開。
接下來輸入的m行資料中,每行包含n個整數,整數之間以一個空格分開。
輸出
輸出對應矩陣的邊緣元素和
- 樣例輸入
- 樣例輸出
樣例
- #include<iostream>
- using namespace std;
- int s;
- int main()
- {
- int n,m;
- cin>>n>>m;
- for(int i=;i<=n;i++)
- for(int j=;j<=m;j++)
- {
- int x;
- cin>>x;
- if(i==||i==n||j==||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
- 樣例輸入2
- 樣例輸入3
- 樣例輸出
- 樣例輸出1
- OK
- 樣例輸出2
- 樣例輸出3
- Corrupt
樣例
因為元素只是0或1,所以統計每一行和每一列的和。
滿足第二條要求,當且僅當行和列各有一個的和是奇數才行。可以先判斷是否滿足這個情況,
如果滿足,輸出記錄下來的第一個行、列為奇數的座標(如果有多個,那麼一定不滿足這個條件,所以只需要記錄第一個)
如果不滿足,則要麼行或列有一個的和為奇數,要麼和或列至少有一個出現多個和為奇數的情況,這兩種情況都不滿足要求,所以只需要再判斷是否還有和為奇數的行或列即可,有則不符合以上兩條,輸出Corrupt,沒有則輸出OK
- #include<iostream>
- using namespace std;
- int h[],l[];
- int n;
- int x,y,dx,dy;//x統計和為奇數的行的總數,y統計列,dx為第一個出現行為奇數的行號,dy為列號
- int main()
- {
- cin>>n;
- for(int i=;i<=n;i++)
- for(int j=;j<=n;j++)
- {
- int x;
- cin>>x;
- h[i]+=x;
- l[j]+=x;
- }
- for(int i=;i<=n;i++)
- {
- if(h[i]&) x++,dx=i;
- if(l[i]&) y++,dy=i;
- }
- if(x==&&y==) cout<<dx<<' '<<dy;
- else if(x>||y>) cout<<"Corrupt";
- else cout<<"OK";
- }
開始做時有兩個錯誤:
① 在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不是鞍點,以此類推,可證明矩陣只有一個鞍點
- 樣例輸入
- 樣例輸出
樣例
- #include<iostream>
- using namespace std;
- int a[][];
- bool ok;
- int main()
- {
- for(int i=;i<=;i++)
- for(int j=;j<=;j++)
- cin>>a[i][j];
- for(int i=;i<=;i++)//列舉每一行
- {
- int max_h=-0x7fffffff,k=;//max_h,當前行的最大值;k,max_h所在列
- for(int j=;j<=;j++)
- if(a[i][j]>max_h)
- {
- max_h=a[i][j];k=j;
- }
- int min_l=0x7fffffff,q=;//min_l,第k列的最小值;q,min_l所在行
- for(int l=;l<=;l++)
- if(a[l][k]<min_l)
- {
- min_l=a[l][k];q=l;
- }
- if(q==i)
- {
- cout<<i<<' '<<k<<' '<<a[i][k];
- return ;
- }
- }
- 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,表示第二幅黑白影象上各畫素點的顏色。相鄰兩個數之間用單個空格隔開。
輸出
一個實數,表示相似度(以百分比的形式給出),精確到小數點後兩位。
- 樣例輸入
- 樣例輸出
- 44.44
樣例
注意int與double的型別轉換
- #include<iostream>
- #include<cstdio>
- using namespace std;
- int m,n,a[][],s;
- int main()
- {
- cin>>m>>n;
- for(int i=;i<=m;i++)
- for(int j=;j<=n;j++)
- cin>>a[i][j];
- for(int i=;i<=m;i++)
- for(int j=;j<=n;j++)
- {
- int x;
- cin>>x;
- if(x==a[i][j]) s++;
- }
- double k=(double)s/(n*m);
- k*=;
- 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行,每行上的整數為對應矩陣歸零消減過程中,每次消減前位於第二行第二列的元素的值。
- 樣例輸入
- 樣例輸出
樣例
每次找出每一行的最小值減去,找出每一列的最小值減去,刪除第二行第二列時,for迴圈一個一個挪過去
本題題意描述有點兒問題,每次消除第二行、第二列,只有n-1個(2,2),所以當行、列等於1時,輸出上一步的(2,2)才能AC
- #include<iostream>
- using namespace std;
- int a[][];
- int h[],l[];
- int main()
- {
- int n; cin>>n;
- for(int i=;i<=n;i++) for(int j=;j<=n;j++) cin>>a[i][j];
- int s=n;
- for(int k=;k<=s;k++)
- {
- cout<<a[][]<<endl;
- for(int i=;i<=n;i++) h[i]=a[i][];
- for(int i=;i<=n;i++) for(int j=;j<=n;j++) h[i]=min(h[i],a[i][j]);
- for(int i=;i<=n;i++) for(int j=;j<=n;j++) a[i][j]-=h[i];
- for(int i=;i<=n;i++) l[i]=a[][i];
- for(int i=;i<=n;i++) for(int j=;j<=n;j++) l[j]=min(l[j],a[i][j]);
- for(int i=;i<=n;i++) for(int j=;j<=n;j++) a[i][j]-=l[j];
- if(n>)
- {
- for(int i=;i<=n;i++) for(int j=;j<n;j++) a[i][j]=a[i][j+];
- for(int i=;i<n;i++) for(int j=;j<=n;j++) a[i][j]=a[i+][j];
- n--;
- }
- }
- }
刪除第二行第二列時,要先判斷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個整數,表示矩陣加法的結果。相鄰兩個整數之間用單個空格隔開。
- 樣例輸入
- 樣例輸出
樣例
矩陣加法:矩陣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
- #include<iostream>
- using namespace std;
- int n,m;
- int a[][];
- int main()
- {
- cin>>n>>m;
- for(int i=;i<=n;i++)
- for(int j=;j<=m;j++)
- cin>>a[i][j];
- for(int i=;i<=n;i++)
- for(int j=;j<=m;j++)
- {
- int x;
- cin>>x;
- a[i][j]+=x;
- }
- for(int i=;i<=n;i++)
- {
- for(int j=;j<=m;j++)
- cout<<a[i][j]<<' ';
- cout<<endl;
- }
- }
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個整數,整數之間以一個空格分開。
- 樣例輸入
- 樣例輸出
樣例
矩陣乘法:(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[][],b[][],c[][];
- int main()
- {
- cin>>n>>m>>k;
- for(int i=;i<=n;i++)
- for(int j=;j<=m;j++)
- cin>>a[i][j];
- for(int i=;i<=m;i++)
- for(int j=;j<=k;j++)
- cin>>b[i][j];
- for(int i=;i<=n;i++)
- for(int j=;j<=m;j++)
- for(int l=;l<=k;l++)
- c[i][l]+=a[i][j]*b[j][l];
- for(int i=;i<=n;i++)
- {
- for(int j=;j<=k;j++)
- cout<<c[i][j]<<' ';
- cout<<endl;
- }
- }
1
- #include<iostream>
- using namespace std;
- int n,m,k;
- int a[][],b[][],c[][];
- int main()
- {
- cin>>n>>m>>k;
- for(int i=;i<=n;i++)
- for(int j=;j<=m;j++)
- cin>>a[i][j];
- for(int i=;i<=m;i++)
- for(int j=;j<=k;j++)
- cin>>b[i][j];
- for(int i=;i<=n;i++)
- for(int j=;j<=k;j++)
- for(int l=;l<=m;l++)
- c[i][j]+=a[i][l]*b[l][j];
- for(int i=;i<=n;i++)
- {
- for(int j=;j<=k;j++)
- cout<<c[i][j]<<' ';
- cout<<endl;
- }
- }
2
T10 矩陣轉置
描述
輸入一個n行m列的矩陣A,輸出它的轉置AT。
輸入
第一行包含兩個整數n和m,表示矩陣A的行數和列數。1 <= n <= 100,1 <= m <= 100。
接下來n行,每行m個整數,表示矩陣A的元素。相鄰兩個整數之間用單個空格隔開,每個元素均在1~1000之間。
輸出
m行,每行n個整數,為矩陣A的轉置。相鄰兩個整數之間用單個空格隔開。
矩陣轉置即行列交換後輸出。例:
- 樣例輸入
- 樣例輸出
樣例
- #include<iostream>
- using namespace std;
- int n,m,a[][];
- int main()
- {
- cin>>n>>m;
- for(int i=;i<=n;i++)
- for(int j=;j<=m;j++)
- cin>>a[i][j];
- for(int i=;i<=m;i++)
- {
- for(int j=;j<=n;j++)
- cout<<a[j][i]<<' ';
- cout<<endl;
- }
- }