这次的题目根据身边同学反映普遍较难,仔细看了一下题目其实也并不难,因为都没有涉及比较复杂的算法,但是这次的题目都比较繁琐,写起来比较费时间。
题目一
题目描述:
已知有一堆人排成M行N列,(M,N均大于等于10小于等于1000),现在从这群人中挑选一些人出来。在这个M行N列的队伍中,每个人对应一个坐标,从最左上角的(0,0)到右下角的(M-1,N-1)。这些人还会进行一次报数,报数顺序是按照类似蜗牛壳形状的顺时针方向由外圈像内圈报数,当报数的个位数为7且十位数为奇数的人出列,按报数顺序输出这些人的坐标。
例如:如下图所示一个5行5列的队伍,按顺时针顺序从外到里报数,其中17满足条件,因此需要输出17的坐标(1,1)
输入和输出格式:
输入为行数M和列数N
10 10
输出为满足条件的坐标:
[[7,9],[1,1],[8,2],[7,5],[4,4]]
要注意输出时候有个坑,前面几组输出坐标后还会输出一个逗号分隔,最后一组坐标之后不输出逗号,因此需要把最后一个满足条件的坐标找出来,输出得时候不输出逗号。
第一题思路
思路比较清晰,就是先创建一个M行N列纯0的数组,然后按照这个顺时针的顺序走一遍下来,并给每个坐标位置赋值(值为这个位置报数号)。然后把满足出列条件的报数的坐标输出即可。按照顺序走的时候需要按照以下的顺序来走:
- 如果该坐标的左边和上边位置已经报过数,且右边位置还未报数,则该位置报数之后向右继续报数。
- 如果该坐标的右边和上边位置已经报过数,且下边位置还未报数,则该位置报数之后向下继续报数。
- 如果该坐标的右边和下边位置已经报过数,且左边位置还未报数,则该位置报数之后向下继续报数。
- 如果该坐标的左边和下边位置已经报过数,且上边位置还未报数,则该位置报数之后向上继续报数。
上面报数的意思其实就是给二维数组赋值的过程,需要注意的是首先要先把最外圈的报数完,因为在进行判断的时候会查询这些坐标相邻外圈元素的状态,如果不先把最外圈的报数,在后面访问时数组会越界。
第一题代码
#include<iostream>
using namespace std;
int main()
{
int M,N;
cin >> M >> N;
int sum0=M*N;//从后往前找找最后一个满足条件的计数。
while(sum0>0)
{
int r1 = sum0 % 100;
int x1 = r1 % 10;
r1 = r1 / 10;
int x2 = r1;
if(x1==7&&x2%2==1)
break;
sum0--;//sum0此时为最后一个满足条件的计数
}
int a[M][N];
for (int i0 = 0; i0 < M; i0++)
for (int j0 = 0; j0 < N; j0++)
a[i0][j0] = 0;
int count = 1;
int i = 0, j = 0;
cout << '[';
while (a[i][j] == 0)
{
a[i][j] = count;
count++;
int s0 = a[i][j];
int r0=s0%100;//除以100的余数为后两位数,用r0记录。
int y1 = r0 % 10;//y1为个位数
r0 = r0 / 10;
int y2 = r0;//y2为十位数
if(y1==7