noi题库(noi.openjudge.cn) 1.8编程基础之多维数组T11——T20
Posted 日拱一卒 功不唐捐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了noi题库(noi.openjudge.cn) 1.8编程基础之多维数组T11——T20相关的知识,希望对你有一定的参考价值。
T11 图像旋转
描述
输入一个n行m列的黑白图像,将它顺时针旋转90度后输出。
输入
第一行包含两个整数n和m,表示图像包含像素点的行数和列数。1 <= n <= 100,1 <= m <= 100。
接下来n行,每行m个整数,表示图像的每个像素点灰度。相邻两个整数之间用单个空格隔开,每个元素均在0~255之间。
输出
m行,每行n个整数,为顺时针旋转90度后的图像。相邻两个整数之间用单个空格隔开。
样例输入 3 3 1 2 3 4 5 6 7 8 9 样例输出 7 4 1 8 5 2 9 6 3
以矩阵元素坐标为例:
1,1 1,2 1,3 顺时针旋转后为 2,1 1,1
2,1 2,2 2,3 2,2 1,2
2,3 1,3
所以输出时第一重循环i正着循环每一列,第二重循环j倒着循环每一行,依次输出(j,i)
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=n;j>=1;j--) 13 cout<<a[j][i]<<\' \'; 14 cout<<endl; 15 } 16 }
T12 变换的矩阵
描述
有一个N x N(N为奇数,且1 <= N <= 10)的矩阵,矩阵中的元素都是字符。这个矩阵可能会按照如下的几种变幻法则之一进行变幻(只会变幻一次)。
现在给出一个原始的矩阵,和一个变幻后的矩阵,请编写一个程序,来判定原始矩阵是按照哪一种法则变幻为目标矩阵的。
1. 按照顺时针方向旋转90度;
如:
1 2 3 7 4 1
4 5 6 变幻为 8 5 2
7 8 9 9 6 3
2. 按照逆时针方向旋转90度;
如:
1 2 3 3 6 9
4 5 6 变幻为 2 5 8
7 8 9 1 4 7
3. 中央元素不变(如下例中的 5),其他元素(如下例中的3)与“以中央元素为中心的对应元素”(如下例中的7)互换;
如:
1 2 3 9 8 7
4 5 6 变幻为 6 5 4
7 8 9 3 2 1
4. 保持原始矩阵,不变幻;
5. 如果 从原始矩阵 到 目标矩阵 的变幻,不符合任何上述变幻,请输出5
输入
第一行:矩阵每行/列元素的个数 N;
第二行到第N+1行:原始矩阵,共N行,每行N个字符;
第N+2行到第2*N+1行:目标矩阵,共N行,每行N个字符;
输出
只有一行,从原始矩阵 到 目标矩阵 的所采取的 变幻法则的编号。
样例输入 5 a b c d e f g h i j k l m n o p q r s t u v w x y y x w v u t s r q p o n m l k j i h g f e d c b a 样例输出 3
方法1(比较麻烦,但是快用时1ms,时间复杂度n²—4n²):记录下原始矩阵每一种变换情况后的矩阵,然后与目标矩阵对比
1,1 1,2 1,3 顺时针旋转后为 2,1 1,1
2,1 2,2 2,3 2,2 1,2
2,3 1,3
所以记录时第一重循环i正着循环每一列,第二重循环j倒着循环每一行,依次记录a[j][i]
1,1 1,2 1,3 逆时针旋转后为 1,3 2,3
2,1 2,2 2,3 1,2 2,2
1,1 2,1
所以记录时第一重循环i正着循环每一行,第二重循环j倒着循环每一列,依次记录a[i][j]
情况3也就是将整个矩阵旋转180°,所以记录时两重循环都倒着循环
1 #include<iostream> 2 #include<cstdlib> 3 using namespace std; 4 int n; 5 char a[11][11],b[11][11],c[11][11]; 6 void case1() 7 { 8 int x=0,y=0; 9 for(int i=1;i<=n;i++) 10 { 11 x++;y=0; 12 for(int j=n;j>=1;j--) 13 c[x][++y]=a[j][i]; 14 for(int k=1;k<=n;k++) 15 if(c[x][k]!=b[x][k]) 16 return; 17 } 18 cout<<\'1\'; 19 exit(0); 20 } 21 void case2() 22 { 23 int x=0,y=0; 24 for(int i=n;i>=1;i--) 25 { 26 x++;y=0; 27 for(int j=1;j<=n;j++) 28 c[x][++y]=a[j][i]; 29 for(int k=1;k<=n;k++) 30 if(c[x][k]!=b[x][k]) 31 return ; 32 } 33 cout<<\'2\'; 34 exit(0); 35 } 36 void case3() 37 { 38 int x=0,y=0; 39 for(int i=n;i>=1;i--) 40 { 41 x++;y=0; 42 for(int j=n;j>=1;j--) 43 c[x][++y]=a[i][j]; 44 for(int k=1;k<=n;k++) 45 if(c[x][k]!=b[x][k]) 46 return; 47 } 48 cout<<\'3\'; 49 exit(0); 50 } 51 void case4() 52 { 53 for(int i=1;i<=n;i++) 54 for(int j=1;j<=n;j++) 55 if(a[i][j]!=b[i][j]) 56 return; 57 cout<<\'4\'; 58 exit(0); 59 } 60 int main() 61 { 62 cin>>n; 63 for(int i=1;i<=n;i++) 64 for(int j=1;j<=n;j++) 65 cin>>a[i][j]; 66 for(int i=1;i<=n;i++) 67 for(int j=1;j<=n;j++) 68 cin>>b[i][j]; 69 case1(); 70 case2(); 71 case3(); 72 case4(); 73 cout<<\'5\'; 74 return 0; 75 }
方法2(代码较短,但慢一点,9ms,时间复杂度,固定4n²):
省去方法1中的记录,直接根据目标矩阵与原矩阵变换后元素的位置关系判断。所以需要判断完所有位置才能出结果
顺时针旋转目标数组b[i][j]对应原数组a[n-j+1][i]
逆时针旋转目标数组b[i][j]对应原数组a[j][n-i+1]
中心对称目标数组b[i][j]对应原数组a[n-i+1][n-j+1]
1 #include<iostream> 2 using namespace std; 3 int n; 4 char a[101][101],b[101][101]; 5 bool p[5]; 6 int main() 7 { 8 cin>>n; 9 for(int i=1;i<=n;i++) 10 for(int j=1;j<=n;j++) 11 cin>>a[i][j]; 12 for(int i=1;i<=n;i++) 13 for(int j=1;j<=n;j++) 14 cin>>b[i][j]; 15 for(int i=1;i<=n;i++) 16 for(int j=1;j<=n;j++) 17 { 18 if(b[i][j]!=a[n-j+1][i]) p[1]=true; 19 if(b[i][j]!=a[j][n-i+1]) p[2]=true; 20 if(b[i][j]!=a[n-i+1][n-j+1]) p[3]=true; 21 if(b[i][j]!=a[i][j]) p[4]=true; 22 } 23 for(int i=1;i<=4;i++) 24 if(!p[i]) 25 { 26 cout<<i;return 0; 27 } 28 cout<<\'5\'; 29 }
T13 图像模糊处理
描述
给定n行m列的图像各像素点的灰度值,要求用如下方法对其进行模糊化处理:
1. 四周最外侧的像素点灰度值不变;
2. 中间各像素点新灰度值为该像素点及其上下左右相邻四个像素点原灰度值的平均(舍入到最接近的整数)。
输入
第一行包含两个整数n和m,表示图像包含像素点的行数和列数。1 <= n <= 100,1 <= m <= 100。
接下来n行,每行m个整数,表示图像的每个像素点灰度。相邻两个整数之间用单个空格隔开,每个元素均在0~255之间。
输出
n行,每行m个整数,为模糊处理后的图像。相邻两个整数之间用单个空格隔开。
样例输入 4 5 100 0 100 0 50 50 100 200 0 0 50 50 100 100 200 100 100 50 50 100 样例输出 100 0 100 0 50 50 80 100 60 0 50 80 100 90 200 100 100 50 50 100
四舍五入可以用函数round,也可以用printf(”.0lf“,x);
1 #include<iostream> 2 #include<cmath> 3 using namespace std; 4 int n,m,a[101][101],b[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 if(i==1||i==n||j==1||j==m) 15 b[i][j]=a[i][j]; 16 else 17 { 18 double r=((double)a[i][j]+a[i-1][j]+a[i+1][j]+a[i][j-1]+a[i][j+1])/5; 19 b[i][j]=round(r); 20 } 21 } 22 for(int i=1;i<=n;i++) 23 { 24 for(int j=1;j<=m;j++) 25 cout<<b[i][j]<<\' \'; 26 cout<<endl; 27 } 28 }
T14 扫雷游戏地雷数计算
描述
扫雷游戏是一款十分经典的单机小游戏。它的精髓在于,通过已翻开格子所提示的周围格地雷数,来判断未翻开格子里是否是地雷。
现在给出n行m列的雷区中的地雷分布,要求计算出每个非地雷格的周围格地雷数。
注:每个格子周围格有八个:上、下、左、右、左上、右上、左下、右下。
输入
第一行包含两个整数n和m,分别表示雷区的行数和列数。1 <= n <= 100, 1 <= m <= 100。
接下来n行,每行m个字符,‘*’表示相应格子中是地雷,‘?’表示相应格子中无地雷。字符之间无任何分隔符。
输出
n行,每行m个字符,描述整个雷区。若相应格中是地雷,则用‘*’表示,否则用相应的周围格地雷数表示。字符之间无任何分隔符。
样例输入 3 3 *?? ??? ?*? 样例输出 *10 221 1*1
两种思路:1、统计出每个地雷的位置,以地雷为基准,周围8个非地雷的格子+1。预测应该比第二种方法快
2、以每一个格子为基准,枚举周围8个格子。时间复杂度O(8n²)
在此只提供第一种方法的代码
1 #include<iostream> 2 using namespace std; 3 int n,m,b[101][101],cnt; 4 int dx[8]={-1,-1,-1,0,1,1,1,0}; 5 int dy[8]={-1,0,1,1,1,0,-1,-1}; 6 int x[10001],y[10001]; 7 char a[101][101]; 8 int main() 9 { 10 cin>>n>>m; 11 for(int i=1;i<=n;i++) 12 for(int j=1;j<=m;j++) 13 { 14 cin>>a[i][j]; 15 if(a[i][j]==\'*\') 16 { 17 x[++cnt]=i;y[cnt]=j; 18 } 19 } 20 for(int i=1;i<=cnt;i++) 21 { 22 int xx=x[i],yy=y[i]; 23 for(int j=0;j<8;j++) 24 { 25 int nx=xx+dx[j],ny=yy+dy[j]; 26 if(nx>0&&nx<=n&&ny>0&&ny<=m&&a[nx][ny]!=\'*\') 27 b[nx][ny]++; 28 } 29 } 30 for(int i=1;i<=n;i++) 31 { 32 for(int j=1;j<=m;j++) 33 if(a[i][j]==\'*\') cout<<\'*\'; 34 else cout<<b[i][j]; 35 cout<<endl; 36 } 37 }
T15 细菌的繁殖与扩散
描述
在边长为9的正方形培养皿中,正中心位置有m个细菌。假设细菌的寿命仅一天,但每天可繁殖10个后代,而且这10个后代,有两个分布在原来的单元格中,其余的均匀分布在其四周相邻的八个单元格中。求经过n(1≤n≤4)天后,细菌在培养皿中的分布情况。
输入
输入为两个整数,第一个整数m表示中心位置细菌的个数(2 ≤ m ≤ 30),第二个整数n表示经过的天数(1 ≤ n ≤ 4)。
输出
输出九行九列整数矩阵,每行的整数之间用空格分隔。整个矩阵代表n天后细菌在培养皿上的分布情况。
样例输入 2 1 样例输出 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 0 0 0 0 0 0 2 4 2 0 0 0 0 0 0 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
三维数组a[k][i][j]代表第k天后矩阵[i,j]位置的细菌数,每次更新时,由于细菌寿命只有一天,所以新的a[k][i][j]=a[k-1][i][j]*2+a[k-1][ni][nj],ni,nj为[i,j]周围的八个单元格
1 #include<iostream> 2 using namespace std; 3 int m,n; 4 int dx[8]={-1,-1,-1,0,1,1,1,0}; 5 int dy[8]={-1,0,1,1,1,0,-1,-1}; 6 int a[5][10][10]; 7 int main() 8 { 9 cin>>m>>n; 10 a[0][5][5]=m; 11 for(int k=1;k<=n;k++)//枚举每一天 12 { 以上是关于noi题库(noi.openjudge.cn) 1.8编程基础之多维数组T11——T20的主要内容,如果未能解决你的问题,请参考以下文章noi题库(noi.openjudge.cn) 1.8编程基础之多维数组T21——T25
noi题库(noi.openjudge.cn) 1.9编程基础之顺序查找T01——T05
noi题库(noi.openjudge.cn) 1.8编程基础之多维数组T11——T20
noi题库(noi.openjudge.cn) 1.9编程基础之顺序查找T06——T15