4.29 京东笔试 题解

两个题 都AC了  尝试发一下题解
1、就是一个尝试的模型。我这里让n 表示较大的,k表示较小的。
考虑1-n 每一个位置
边界:n-k+1 此时可以竖着放,可以横着放,放完之后没有别的选择,返回2
大于边界位置  只能竖着  所以1
其他  就是尝试每一个位置  如果竖着放  那可以去 下一个位置
横着放  长度是k  意味着下面的全是横着  所以去i+k
这样写只能82%  超时   于是 dp优化一下

package jd.c01;

import java.util.HashMap;
import java.util.Scanner;
/*
题目描述:
Alice需要用n块相同的大小为1*k的方形地砖铺满一块大小为n*k的地板。她数学不是很好,所以希望你帮她计算有多少种不同的铺法。

如下图,使用5块大小为1*3的方形地砖铺满一块大小为5*3的地板总共有四种铺法。
输入仅包含一行,这行仅包含两个数n(1<=n<=10000),k(1<=k<=1000),代表题目中的参数。
输出所求的答案。因为答案可能很大,你只需要输出答案除以998244353所得的余数。
 */
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt(), k = in.nextInt();
        int max = Math.max(n, k);
        int min = max==n ? k: n;
        System.out.println(prcoessdp(max, min));
        //System.out.println(process(max, min, 1, new HashMap<>()));
    }
    //n > k
    public static long process(int n, int k, int index, HashMap<Integer, Long> map){
        if(map.containsKey(index)){
            return  map.get(index);
        }
        if(index > n) return  -1;
        long ans = 0;
        if(index == n-k+1){
           // ans =  process(n, k, index+1, map) + 1;
            ans = 2;
        }else if(index > n-k+1){
            ans= 1;
        }else{
            long p1= process(n,k,index+1, map);
            long p2 = process(n,k,index+k, map);
            p1 = p1 % 998244353;
            p2 = p2 % 998244353;
            if(p1 == -1) p1=0;
            if(p2 == -1) p2=0;
            ans = p1+p2;
        }
        ans = ans % 998244353;
        map.put(index, ans);
        return  ans;
    }

    public static long prcoessdp(int n, int k){
        long[] dp = new long[n+1];
        for(int i = n; i > n-k+1;i--)
            dp[i] = 1;
        dp[n-k+1] = 2;
        for(int i = n-k+1-1; i >= 1; i--){
            long p1 = 0, p2 = 0;
            if(i+k <= n){
                p1 = dp[i+k];
            }
            p2 = dp[i+1];
            dp[i] = (p1+p2)% 998244353;
        }

        return  dp[1];
    }
}

2、最开始想法 一个一个试 好复杂
最后:构建一张图,每一个点计算  他们的距离  认为是图的一个边
prim最小生成树   求最小生成树的  最大边  是多长  就可以了

代码里那个max min啥的 没用哈   都是自己的最开始想法  不对(最开始以为求所有距离的 最大值 )
package jd.c02;

import java.util.Scanner;
/*
       Alice和Bob需要采购会议场馆内的无线路由器。每一种路由器有一个参数k用于度量其通信距离。将场馆视为一个二维平面并将路由器视为该平面上的点,两台参数为k的路由器只能在他们所在位置的曼哈顿距离不超过k的前提下直接通信。两个点(x1,y1)和(x2,y2)之间的曼哈顿距离被定义为|x1-x2|+|y1-y2|。

       给出场馆内需要安装无线路由器的所有位置的坐标,请你计算出若他们只采购一种路由器,则其参数k至少需要为多少才能使得任意两个路由器之间都能够互相通信。

       能够互相通信的定义如下:存在一个路由器序列v1,v2,…,vc,该序列中任意两个相邻路由器之间可以直接连接,则v1和vc之间可以互相通信。
 */
/*
第一行有一个正整数n(1<=n<=1000),代表需要安装路由器的位置数量。

第二行有n个整数,第i个代表编号为i的位置的x坐标。

第三行有n个整数,第i个代表编号为i的位置的y坐标。

坐标的绝对值不超过1000000000。
输出一个正整数,代表能够使得任意两个路由器在允许中继的前提下能够互相通信的参数的最小值。
 */
public class Main {
    static long[] x;
    static long[] y;
    static  int n;
    public static void main(String[] args) {
        //System.out.println(Long.MAX_VALUE);
        Scanner in= new Scanner(System.in);
        n = in.nextInt();
        x = new long[n];
        y = new long[n];
        long xmax=Long.MIN_VALUE, xmin=Long.MAX_VALUE, ymax=Long.MIN_VALUE, ymin=Long.MAX_VALUE;
        for(int i=0; i < n;i++){
            x[i] = in.nextLong();
            xmax = Math.max(xmax, x[i]);
            xmin = Math.min(xmin, x[i]);
        }

        for(int i=0; i < n;i++){
            y[i] = in.nextLong();
            ymax = Math.max(ymax, y[i]);
            ymin = Math.min(ymin, y[i]);
        }

        Long max = Long.MIN_VALUE;
        Long min = Long.MAX_VALUE;
        long[][] graph = new long[n][n];
        for(int i = 0; i < n; i++)
            for(int j = 0; j <n; j++)
                graph[i][j] = Long.MAX_VALUE;
        for(int i = 0; i < n; i++){
            for(int j = i+1; j < n; j++){
                long dis = distance(i, j);
                graph[i][j] = dis;
                graph[j][i] = dis;
                max = Math.max(max, dis);
                min = Math.min(min, dis);
            }
        }


        //左下角的点  右上角的点
        long ans = prim(graph);
        if(ans == -1)
            System.out.println(max);
        else
            System.out.println(ans);

    }
    public static long distance(int i, int j){
        long x1 = Math.abs(x[i]-x[j]);
        long y1 = Math.abs(y[i] - y[j]);
        return x1 + y1;
    }
    public static long prim(long[][] graph){
        long[] dis = new long[n];
        boolean[] isVisit = new boolean[n];
        isVisit[0] = true;
        long ans = Long.MIN_VALUE;
        for(int i = 0; i < n; i++){
            dis[i] = graph[0][i];
        }
        for(int i = 1; i < n; i++){
            long minPath = Long.MAX_VALUE;
            int index = -1;
            for(int j = 0; j < n; j++){
                if(!isVisit[j] && dis[j] < minPath){
                    minPath = dis[j];
                    index = j;
                }
            }
            if(index == -1){
                return -1;
            }
            isVisit[index] =true;
            ans = Math.max(ans, minPath);
            for(int j = 0; j < n; j++){
                if(!isVisit[j] && dis[j] > graph[index][j]){
                    dis[j] = graph[index][j];
                }
            }
        }
        return  ans;
    }
}


#京东#
全部评论
刚才在打游戏,重新写一下思路。 1、来到i位置,那你的选择要么竖着放,要么横着放。 竖着放的话,那就去 i+1 位置做选择  process(i+1) 横着放的话,因为1*k  n个  你水平放了 意味着下面必须全是横着,所以相当于占了k个位置,那就应该去 i+k位置做选择。   剩下的就是边界,如果水平放不了了,只能全竖着放,对应1中。如果恰好k*k,只能全水平 或者全垂直。 2、给了图的一些点的坐标,即i号店  他的x为x[i]   y为y[i],那么我把这个想象成一张图,用long[][] graph表示,两个点的距离也就有了(曼哈顿距离),到达不了的认为是最大值。 剩下的就是用PRIM 最小生成树算法,因为要保证能连着,所以最小生成树是保证联通的  需要最少的边了。因此prim里面统计  每一次加边的max值。最后返回的 就是最小生成树的边的最大值,也就是要的答案了。
1 回复 分享
发布于 2022-04-29 21:51
生成树和最小生成树有许多重要的应用。 例如:要在n个城市之间铺设光缆,主要目标是要使这 n 个城市的任意两个之间都可以通信,但铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同,因此另一个目标是要使铺设光缆的总费用最低。这就需要找到带权的最小生成树。 来自: https://baike.quark.cn/c/lemma/15686136457775#/index
点赞 回复 分享
发布于 2022-04-30 09:23
我有一个疑问,最小生成树能保证连通的前提下总距离最小,但是能保证连通域中的最长边最短吗
点赞 回复 分享
发布于 2022-04-30 09:16
京东的笔试算是我目前体验最差的,抛开范围过广的选择题不谈,代码题只有两个且全是hard级别,真有这么多人会手撕最小生成树吗😅是不是下次再考个手撕迪杰斯特拉😅选择题一半蒙,算法题0.18/2,拜拜了狗东
点赞 回复 分享
发布于 2022-04-30 00:44
10天前我曾在没有准备的情况下写出了克鲁斯卡尔,而今天时间充足,有所准备,温度适中的情况下,写错了prim并且坚定的认为题目错了🤣
点赞 回复 分享
发布于 2022-04-30 00:28
根本没看出来是最小生成树,只对了36%。。。
点赞 回复 分享
发布于 2022-04-29 22:23
知道第二题应该最小生成树,但是考研之后再也没写过,看到题直接人傻了😭
点赞 回复 分享
发布于 2022-04-29 22:15

相关推荐

点赞 评论 收藏
分享
评论
4
11
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务