华为实习笔试复盘(1)配送站和客户问题

写在前面

自己玩了很多项目,但是最近准备秋招的过程中,发现自己对于算法和编程语言的基本功夫实在是太欠缺了。
投递了华为的实习岗位,4.26参加机考,一做题就发现了自己很多地方都不会。这里写下笔试后的复盘以警醒自己。

题目

按照记忆来回顾题目,仅供参考。解法为自己复盘所写,没有经过数据集测试,不保真。
如果有发现问题,欢迎提出,非常感谢!
机考第一题,分值(100分)

题目描述

在n*n的矩阵范围内,有K个配送站和N个客户点,配送点和客户的坐标给出。如何计算最短路径让K个配送点能够全部覆盖N个客户点。配送站和客户点的距离表示如:distance = |x1-x2| + |y1 - y2|

解题思路

复盘的时候,理解到这道题是一个匹配问题。
解题思路如下:

  • 先建立配送站和客户点的位置地图。地图大小是n*n矩阵,并将配送站和客户点的位置存储。
  • 求出所有配送站与客户的距离distance_all[K][N],并在计算的过程中记录最大距离max_distance。下图中D[K][N]表示第K的配送点和第N的客户的距离
    在这里插入图片描述
  • 然后开始从0到max_distance开始循环,每次循环的值为distance,再对距离数组先从上到下遍历,再从左到右遍历。
  • 如果在该列中存在D小于distance,那么代表有一个配送站能到达此客户点,那么跳出此列,进入下一列,直至遍历所有列。如果有一列不存在D小于distance,说明有一个客户点没有配送站能到达,那么跳出行遍历,distance++
  • 由于一定存在一个distance能够满足要求,因此无需考虑不存在distance的情况。如果行列遍历均结束,则跳出distance循环,并输出当前distance
    在这里插入图片描述

代码

因为是笔试后复盘,未经过数据集检验。解法也不一定是最优解。如果有问题或者别的思路,欢迎提出。

#include <stdio.h>      
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main()
{
    
    
    int R,C;
    scanf("%d %d", &R, &C);                             //扫描矩阵范围行*列:R*C
    //printf("%d", R);
    int people_num;
    scanf("%d", &people_num);                           //扫描客户数量
    //printf("%d", people_num);
    int R_location[people_num],C_location[people_num];  //初始化地图矩阵
    for(int i=0; i<people_num; i++)
    {
    
    
        scanf("%d %d", &R_location[i],&C_location[i]);  //获得客户的地址
        //printf("\n%d %d\n", R_location[i],C_location[i]);
    }

    int send;
    scanf("%d", &send);                                 //配送站的数量
    int R_send[send],C_send[send];
    int distance_all[send][people_num];                 //配送站到客户的距离
    for(int i=0; i<send; i++)
    {
    
    
        scanf("%d %d", &R_send[i],&C_send[i]);          //配送站的地址
        //printf("\n%d %d\n", R_send[i],C_send[i]);
    }

    //计算每个配送站到客户的距离并存储到distance_all中,并存储最大距离
    int max_distance=0;
    for(int i=0; i<send; i++){
    
    
        for(int j=0; j<people_num; j++){
    
                    
            distance_all[i][j] = abs(R_send[i]-R_location[j]) + abs(C_send[i] - C_location[j]);
            if(distance_all[i][j] > max_distance)
                max_distance = distance_all[i][j];
            printf("%d ",distance_all[i][j]);
        }
    }
    printf("\n");
    //从最短配送距离0到最长配送距离max_distance,因为最大的可能就是max_distance
    int distance = 0,i=0,j=0;
    for(distance = 0; distance<=max_distance; distance++){
    
    
        for(i=0; i<people_num; i++){
    
    

            for(j=0; j<send; j++){
    
                    
                if(distance_all[j][i] <= distance)
                    break;
            //printf("%d ",distance_all[i][j]);
            }
            if(j >= send)   //如果配送站到某一个用户距离比当前距离大,说明该用户无法被配送到,距离更新
                break;
        }
        if(i >= people_num) //如果有一个距离满足了所有用户都至少有一个配送站能到,说明该距离已经符号
            break;
    }
    printf("%d",distance);


    return 0;
}

猜你喜欢

转载自blog.csdn.net/scarecrow_sun/article/details/130455199