写在前面
自己玩了很多项目,但是最近准备秋招的过程中,发现自己对于算法和编程语言的基本功夫实在是太欠缺了。
投递了华为的实习岗位,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;
}