四(3)班 张耀夫 数表问题的理解与编程实现
1. 引出题目
今天,我和爸爸有把我们的秘密大门-----数学之门,也就是说,我们又开始玩数学了。
爸爸说今天的题目有点难,给你们透露一下,这种类型的题目之所以难,1.是因为这种类型的题目想好久并且一点提示都不给的情况下是不会有思路的。2.爸爸还给了我一个新的挑战:就是用C++把这道题做出来。我想:爸爸也许是想让我把一题多解习以为常吧。
2. 简单题目
今天有两道题,一道简单一点的,一道难一点的,先说简单一点的,难一点的会这道题的题目上有一个用数字组成的长方形,下面还有一个省略号表示有好多数,让我们求XX在第几行第几列,如下图:
222在第几行第几列?
3.简单题目解析
想了好久之后,爸爸终于给了我一点提示:“这道题可以用等差序列解决哟。”我立马明白了,先用222除以每行的个数,也就是列数5等于44行余2个,44是满行数,余数2说明222在44 + 1 = 45(行),也说明222在第2列,所以答案就是:45行2列。
4.升级题目
难一点的题目给出了一个S型矩阵,行数为偶数的行很特殊:它是倒着的。行数为奇数的行是正常给出的,让我们求XX在第几行第几列,如下图:
105在第几行第几列?
5.升级题目解析
因为题目给出的是一个S形的矩阵,也就是一个S型的数表,所以我们采用的分组的方法是:两行一组。分完组以后用105除以两行加起来的个数,也就是一组的数的个数,然后根据余数的值来分情况计算该数所在的行和列。主要分为以下三种情况:
(1)余数在1和列数之间,也就是该数位于奇数行;
(2)余数大于列数,也就是该数位于偶数行,为倒序排列;
(3)余数为0,该数位于偶数行,且为偶数行第一个
具体实现流程图如下图所示,我和爸爸还写了一个C++的程序实现了这个流程,感兴趣的同学可以看看。
6.流程图表示升级题目
7. 代码
//作者:张耀夫和他的爸爸
//时间:2月4日
//程序功能:输入行数和列数,输出s型矩阵,再输入矩阵中的某个数,求它的位置。
#include <iostream>
using namespace std;
int a[110][110];
int main() {
int cnt = 0;
int x;
int y;
cin >> x;
cin >> y;
//生成s型矩阵
for (int i = 0;i < x;i++){
//判断要不要倒序输出
if (i % 2 == 0){
//如果是奇数行,正常输出
for (int j = 0;j < y;j++){
cnt++;
a[i][j] = cnt;
}
}
else{
//倒序输出
for (int j = y - 1;j >= 0;j--){
cnt++;
a[i][j] = cnt;
}
}
}
//2重循环输出s型2维数组/矩阵
for (int i = 0;i < x;i++){
//输出s型矩阵
for (int j = 0;j < y;j++){
cout << a[i][j] << " ";
}
cout << endl;
}
int b;//输入变量
cin >> b;
int c;//输出的行
int r;//输出的列
//2行一组,判断输入的数除以一组的个数的余数是否大于列数
if (b % (2 * y) > y){
//如果是,行数等于组数乘2加2,列数需要按照倒序的顺序来求
r = (b / (2*y))*2 + 2;
c = y - (b % y) + 1;
}
//如果输入的数除以一组的的个数的余数小于等于列数
else {
//输入的数在偶数行的第一个个
if (b % (2 * y) == 0){
r = (b / (2*y))*2;
c = 1;
}
//输入的数在奇数行
else {
r = (b / (2*y))*2 + 1;
c = b %(2*y);
}
}
cout << r;
cout << " ";
cout << c;
return 0;
}
8. 大家一起来思考
请问:111111在第几行第几列?
1 |
|
21 |
|
25 |
|
2 |
10 |
20 |
24 |
26 |
34 |
3 |
|
19 |
|
27 |
|
4 |
|
18 |
|
28 |
|
5 |
11 |
17 |
23 |
29 |
35 |
6 |
|
16 |
|
30 |
|
7 |
|
15 |
|
31 |
|
8 |
12 |
14 |
22 |
32 |
36 |
9 |
|
13 |
|
33 |
......... |