zoukankan      html  css  js  c++  java
  • (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
  • 相关阅读:
    c#生成html静态文件时出现空白行,怎么去掉utf-8中的bom
    解决网站发布404返回200,301等状态
    创建本地缓存
    创建windows服务
    C#DateTime与Unix时间戳的转换
    Oracle数据访问组件ODAC的安装方法:
    用任意语言与WebService进行交互
    又一种XML的解析方法
    TopShelf框架创建Windows服务作为Remoting的宿主案例:
    bootstrap 时间控件带(时分秒)选择器(需要修改才能显示,请按照参数说明后面的步骤进行修改)
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/6103849.html
Copyright © 2011-2022 走看看