noi题库(noi.openjudge.cn) 1.8编程基础之多维数组T21——T25

Posted 日拱一卒 功不唐捐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了noi题库(noi.openjudge.cn) 1.8编程基础之多维数组T21——T25相关的知识,希望对你有一定的参考价值。

T21 二维数组右上左下遍历

描述

给定一个row行col列的整数数组array,要求从array[0][0]元素开始,按从左上到右下的对角线顺序遍历整个数组。

输入

输入的第一行上有两个整数,依次为row和col。
余下有row行,每行包含col个整数,构成一个二维整数数组。
(注:输入的row和col保证0 < row < 100, 0 < col < 100)

输出

按遍历顺序输出每个整数。每个整数占一行。

样例输入
3 4
1 2 4 7
3 5 8 10
6 9 11 12
样例输出
1
2
3
4
5
6
7
8
9
10
11
12
样例

先枚举第一行,向左下枚举,再枚举最后一列(除去右上角,因为第一行已经枚举过了)

 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 j=1;j<=m;j++)//枚举第一行 
11     {
12         int i=1,k=j;//i:当前行,k:当前列 
13         while(i<=n&&k>0)//不超边界 
14         {
15             cout<<a[i][k]<<endl;
16             i++;k--;
17         }
18     }
19     for(int i=2;i<=n;i++)//最后一列,从第二行开始 
20     {
21         int j=m,k=i;//j:当前列,k:当前行 
22         while(k<=n&&j>0)//不超边界 
23         {
24             cout<<a[k][j]<<endl;
25             k++;j--;
26         }
27     }
28 }
View Code

第一次枚举最后一列时从第一行开始的,0分。。。。。。

T22 神奇的幻方

描述

幻方是一个很神奇的N*N矩阵,它的每行、每列与对角线,加起来的数字和都是相同的。
我们可以通过以下方法构建一个幻方。(阶数为奇数)
1.第一个数字写在第一行的中间
2.下一个数字,都写在上一个数字的右上方:
    a.如果该数字在第一行,则下一个数字写在最后一行,列数为该数字的右一列
    b.如果该数字在最后一列,则下一个数字写在第一列,行数为该数字的上一行
    c.如果该数字在右上角,或者该数字的右上方已有数字,则下一个数字写在该数字的下方

输入

一个数字N(N<=20)

输出

按上方法构造的2N-1 * 2N-1的幻方

样例输入
3
样例输出
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
样例

类似于NOIP2015 Day1 T1,但这道题是2*n-1阶的

 1 #include<iostream>
 2 using namespace  std;
 3 int n,a[50][50];
 4 int main()
 5 {
 6     cin>>n;
 7     a[1][n]=1;
 8     int i=2,x=1,y=n;
 9     while(i<=(2*n-1)*(2*n-1))
10     {
11         if((x==1&&y==2*n-1)||a[x-1][y+1]) x+=1;
12         else if(x==1) x=2*n-1,y+=1;
13         else if(y==2*n-1) x-=1,y=1;
14         else x-=1,y+=1;
15         a[x][y]=i++;
16     }
17     for(int k=1;k<=2*n-1;k++)
18      {
19          for(int l=1;l<=2*n-1;l++)
20          cout<<a[k][l]<<\' \';
21          cout<<endl;
22      }
23 } 
View Code

T23 二维数组回形遍历

描述

给定一个row行col列的整数数组array,要求从array[0][0]元素开始,按回形从外向内顺时针顺序遍历整个数组。如图所示:

输入

输入的第一行上有两个整数,依次为row和col。
余下有row行,每行包含col个整数,构成一个二维整数数组。
(注:输入的row和col保证0 < row < 100, 0 < col < 100)

输出

按遍历顺序输出每个整数。每个整数占一行。

样例输入
4 4
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
样例输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
样例

递归遍历即可,一定要注意一个格子只能走一遍以及判断是否输出了所有数,不然会递归死循环

 1 #include<iostream>
 2 using namespace std;
 3 int n,m,a[101][101];
 4 bool v[101][101];
 5 bool ok;
 6 bool judge()//判断是否已经输出了所有的数 
 7 {
 8     for(int i=1;i<=n;i++)
 9      for(int j=1;j<=m;j++)
10       if(!v[i][j]) return false;
11     return true;
12 }
13 //R向右 ,D向下,L向左,U向上 
14 void dfs(int x,int y,char p)//x:当前行,y:当前列,p判断向哪儿走 
15 {
16     if(ok) return;//在judge之前先判断是否已经输出了所有点,防止输出完递归回退时多次执行judge函数,浪费时间 
17     ok=judge(); 
18     if(p==\'R\')//可以向右走 
19     {
20         if(x>0&&x<=n&&y>0&&y<=m&&!v[x][y])//不超边界且没有被遍历 
21         {
22             cout<<a[x][y]<<endl;
23             v[x][y]=true;
24             dfs(x,y+1,\'R\');//继续向右走 
25         }
26         else p=\'D\',dfs(x+1,y-1,\'D\');//转为向下走,当执行这个语句时,y已经超出了边界,所以要减1,向下走x+1 
27     }
28     else if(p==\'D\')
29     {
30         if(x>0&&x<=n&&y>0&&y<=m&&!v[x][y])
31         {
32             cout<<a[x][y]<<endl;
33             v[x][y]=true;
34             dfs(x+1,y,\'D\');
35         }
36         else p=\'L\',dfs(x-1,y-1,\'L\');
37     }
38     else if(p==\'L\')
39     {
40         if(x>0&&x<=n&&y>0&&y<=m&&!v[x][y])
41         {
42             cout<<a[x][y]<<endl;
43             v[x][y]=true;
44             dfs(x,y-1,\'L\');
45         }
46         else p=\'U\',dfs(x-1,y+1,\'U\');
47     }
48     else if(p==\'U\')
49     {
50         if(x>0&&x<=n&&y>0&&y<=m&&!v[x][y])
51         {
52             cout<<a[x][y]<<endl;
53             v[x][y]=true;
54             dfs(x-1,y,\'U\');
55         }
56         else p=\'R\',dfs(x+1,y+1,\'R\');
57     }
58 }
59 int main()
60 {
61     cin>>n>>m;
62     for(int i=1;i<=n;i++)
63      for(int j=1;j<=m;j++)
64       cin>>a[i][j];
65     dfs(1,1,\'R\');
66 }
View Code

T24 蛇形填充数组

描述

用数字1,2,3,4,...,n*n这n2个数蛇形填充规模为n*n的方阵。

蛇形填充方法为:

对于每一条左下-右上的斜线,从左上到右下依次编号1,2,...,2n-1;按编号从小到大的顺序,将数字从小到大填入各条斜线,其中编号为奇数的从左下向右上填写,编号为偶数的从右上到左下填写。

比如n=4时,方阵填充为如下形式:

1  2  6  7
3  5  8  13
4  9  12 14
10 11 15 16

输入

输入一个不大于10的正整数n,表示方阵的行数。

输出

输出该方阵,相邻两个元素之间用单个空格间隔。

注意处理边界情况。

               

①:超出矩阵上边界,此时位置坐标已经到①出,列与拐弯后的位置的列相等,行少了1,所以行+1,列不变

②:超出矩阵右边界,此时位置坐标已经到②出,行与拐弯后的位置的行少了2行,列多了一列,所以行+2,列-1

③:即超出上边界,又超出右边界,此时位置到③处,我们可以手算一下,若先执行①,再执行②,会到达A处;先执行②,再执行①,会到达B处,而拐弯后的目标位置为B处,所以在程序中,要先判断②的情况,在判断①的情况。

当然为了避免③的情况,也可以另写一个语句直接判断

如果不是边界,直接行减1,列加1

当向左下方填充时,情况类似,就不再写了

 1 #include<iostream>
 2 using namespace std;
 3 int n,a[11][11];
 4 bool ok;
 5 int main()
 6 {
 7     cin>>n;
 8     int s=0,p=1; 
 9     int x=1,y=1;
10     while(s<n*n)//填充,具体解释看上面的题解
11     {
12         while(p%2==0&&s<n*n)
13         {
14             ok=false;
15             s++;
16             a[x][y]=s;
17             x++;y--;
18             if(x>n) x--,y+=2,ok=true;
19             if(y<1) y++,ok=true;
20             if(ok) p++;
21         }
22         while(p%2==1&&s<n*n)
23         {
24             ok=false;
25             s++;
26             a[x][y]=s;
27             x--;y++;
28             if(y>n) x+=2,y--,ok=true;
29             if(x<1) x++,ok=true;
30             if(ok) p++; 
31         }
32     }
33     for(int i=1;i<=n;i++)
34      {
35          for(int j=1;j<=n;j++)
36           cout<<a[i][j]<<\' \';
37          cout<<endl;
38      }
39 } 
View Code

一开始没考虑③的情况,先判断的①,在判断的②,导致对角线拐弯时错行

T25 螺旋加密

描述

Chip和Dale发明了一种文本信息加密技术。他们事先秘密约定好矩阵的行数和列数。接着,将字符按如下方式编码:

1. 所有文本只包含大写字母和空格。

2. 每个字符均赋予一个数值:空格=0,A=1,B=2,……,Y=25,Z=26。

按照下图所示的方式,将每个字符对应数值的5位二进制数依次填入矩阵。最后用0将矩阵补充完整。例如,对于信息“ACM”,行列数均为4时,矩阵将被填充为:

将矩阵中的数字按行连起来形成数字串,完成加密。例子中的信息最终会被加密为:0000110100101100。

输入

一行。首先是两个整数R(1≤R≤20)和C(1≤C≤20),表示行数和列数。之后是一个只包含大写字母和空格的字符串。字符串的长度≤(R*C)/5。R和C之间以及C和字符串之间均用单个空格隔开。

输出

一行,为加密后的二进制串。注意你可能需要用0将矩阵补充完整。

先将字符串按要求转化为二进制数字,然后再用类似T23二维数组回形遍历的方法把数字存到矩阵里,最后按顺序输出。这种方法虽然麻烦点儿,但比较快,用时0ms

注意数据的读入方式,为了防止读入多余的空格或少读空格,可以将一整行当字符串用gets读进去,再找空格分开。也可以多输入一个getchar()语句。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 int n,m,a[101][101];
 6 char s[100];
 7 int ss[1000];
 8 bool v[101][101];
 9 int sum;
10 //R向右 ,D向下,L向左,U向上 
11 void dfs(int x,int y,char p)//x:当前行,y:当前列,p判断向哪儿走 
12 {
13     if(sum==n*m) return;
14     if(p==\'R\')//可以向右走 
15     {
16         if(x>0&&x<=n&&y>0&&y<=m&&!v[x][y])//不超边界且没有被填充
17         {
18             a[x][y]=ss[++sum];
19             v[x][y]=true;
20             dfs(x,y+1,\'R\');//继续向右走 
21         }
22         else p=\'D\',dfs(x+1,y-1,\'D\');//转为向下走,当执行这个语句时,y已经超出了边界,所以要减1,向下走x+1 
23     }
24     else if(p==\'D\')
25     {
26         if(x>0&&x<=n&&y>0&&y<=m&&!v[x][y])
27         {
28             a[x][y]=ss[++sum];
29             v[x][y]=true;
30             dfs(x+1,y,\'D\');
31         }
32         else p=\'L\',dfs(x-1,y-1,\'L\');
33     }
34     else if(p==\'L\')
35     {
36         if(x>0&&x<=n&&y>0&&y<=m&&!v[x][y])
37         {
38             a[x][y]=ss[++sum];
39             v[x][y]=true;
40             dfs(x,y-1,\'L\');
41         }
42         else p=\'U\',dfs(x-1,y+1,\'U\');
43     }
44     else if(p==\'U\')
45     {
46         if(x>0&&x<=n&&y>0&&y<=m&&!v[x][y])
47         {
48             a[x][y]=ss[++sum];
49             v[x][y]=true;
50             dfs(x-1,y,\'U\');
51         }
52         else p=\'R\',dfs(x+1,y+1,\'R\');
53     }
54 }
55 int main()
56 {
57     gets(s);
58     int i;
59     for(i=0;i<strlen(s);i++)//取出行 n 
60      {
61          if(s[i]!=\' \') n=n*10+s[i]-\'0\';
62          else break;
63      }
64     int j;
65     for(j=i+1;j<strlen(s);j++)//取出列 m 
66     {
67         if(s[j]!=\' \') m=m*10+s[j]-\'0\';
68         else break;
69     }
70     int l=0;
71     for(int k=j+1;k<strlen(s);k++) //将字符串转化为二进制 
72      {
73          if(s[k]==\' \')//空格的情况时5个0 
74          for(int u=1;u<=5;u++)  ss[++l]=0;
75          else
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

noi题库(noi.openjudge.cn) 1.7编程基础之字符串T21——T30

noi题库(noi.openjudge.cn) 1.5编程基础之循环控制T37——T38