华为机考,华为笔试,软件类,2020年8月19日题目,超详细解答。

这次的题目根据身边同学反映普遍较难,仔细看了一下题目其实也并不难,因为都没有涉及比较复杂的算法,但是这次的题目都比较繁琐,写起来比较费时间。

题目一

题目描述:

已知有一堆人排成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的数组,然后按照这个顺时针的顺序走一遍下来,并给每个坐标位置赋值(值为这个位置报数号)。然后把满足出列条件的报数的坐标输出即可。按照顺序走的时候需要按照以下的顺序来走:

  1. 如果该坐标的左边和上边位置已经报过数,且右边位置还未报数,则该位置报数之后向右继续报数。
  2. 如果该坐标的右边和上边位置已经报过数,且下边位置还未报数,则该位置报数之后向下继续报数。
  3. 如果该坐标的右边和下边位置已经报过数,且左边位置还未报数,则该位置报数之后向下继续报数。
  4. 如果该坐标的左边和下边位置已经报过数,且上边位置还未报数,则该位置报数之后向上继续报数。
    上面报数的意思其实就是给二维数组赋值的过程,需要注意的是首先要先把最外圈的报数完,因为在进行判断的时候会查询这些坐标相邻外圈元素的状态,如果不先把最外圈的报数,在后面访问时数组会越界。

第一题代码

#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(
  • 10
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值