栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

笔试-hw

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

笔试-hw

第一题

若干算子构成一个有向无环图,若算子A依赖算子B的输出,则仅当算子B执行完成后才能执行A,没有依赖关系的算子可以并行执行。
已知每个算子的执行时间,求整个网络运行所需要的最小时间。

输入描述:
一共N+1行,第一行输入N,即算子总数
第二到第N+1行包括
算子名称 算子消耗时间 后继算子1 后继算子2 … 后继算子k
(可能存在没有后继算子的算子)

思路 Python解法1
N = int(input()) #数据的大小
res = [0] * N #res[i]表示完成第i个任务所需要的最短时间
for i in range(N):
    #处理输入,直接略过第一行数据
    _input = list(map(int,input().split()[1:]))
    if len(_input) < 2: #如果没有
        res[i] += _input[0]
    else:
        for j in _input[1:]:
            res[j] = max(res[j],res[i] + _input[0])
print(max(res))
解法2

有向无环图求一个拓扑排序

N=int(input())
degree={}
matrix={}
op_time={}
father={}
finish_time=[0]*N
for op_idx in range(N):
    matrix[op_idx]=[]
    degree[op_idx]=0
    father[op_idx]=[]

for op_idx in range(N):
    op=input().split()
    op_time[op_idx]=int(op[1])
    for next_op in op[2:]:
        next_op=int(next_op)
        degree[next_op]+=1
        matrix[op_idx].append(next_op)
        father[next_op].append(op_idx)

queue=[]
for op_idx in range(N):
    if degree[op_idx]==0:
        queue.append(op_idx)

tuopu=[]
while len(queue):
    cur_node=queue.pop(0)
    tuopu.append(cur_node)
    for next_node in matrix[cur_node]:
        degree[next_node]-=1
        if degree[next_node]==0:
            queue.append(next_node)

for op_idx in tuopu:
    max_time=0
    for pre_op in father[op_idx]:
        if finish_time[pre_op]>max_time:
            max_time=finish_time[pre_op]
    finish_time[op_idx]=max_time+op_time[op_idx]

print(max(finish_time))
Java处理输入部分
public class Huawei {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = Integer.parseInt(sc.nextLine());
        List> input = new ArrayList<>();
        for (int i = 0; i < N; i++) {
            String[] nums = sc.nextLine().split(" ");
            List suanzi = new ArrayList<>();
            suanzi.add(Integer.parseInt(nums[1]));
            for (int j = 2; j < nums.length; j++) {
                suanzi.add(Integer.parseInt(nums[j]));
            }
            input.add(suanzi);
        }
    }
}
第二题

有若干内存块,每个内存块有不同的规格,对内存进行分配,
求剩余完全没有被分配的内存块总大小的最大值。
输入描述:
第一行N,代表内存块的种类。
接下来的N行每一行有两个数字分别是该种内存的数量和内存大小。
第N+2行是M,代表请求的数量。
第N+3行有M个数字,代表每次请求的内存大小。

举例:

输入:
3
2 4
3 8
4 16
4
7 9 11 4
输出:
64

代表有3种内存,容量为4的内存有2个,容量为8的有3个,容量为16的有4个。
接下来4次请求,分别请求7、9、11、4的内存。
第一次分配容量为16的内存。
第二次分配第一次分配后的剩余内存。
第三次分配容量为16的内存。
第四次分配第三次分配后的剩余内存。
此时剩余大小2*4+3*8+2*16=64的内存块完全没有被分配。

思路

用回溯+剪枝的方法来寻找最优解。
剪枝:如果此时的策略已经不如现存的最好策略就直接跳过

Python解法
class Solution(object):
    def __init__(self, blocks, nums):
        self.blocks = blocks
        self.ans = -1  # 最终的结果
        self.use = [False] * len(blocks)  # 标记每个内存块的使用状态(True 表示已被使用, False表示未使用)
        self.nums = nums
        self.nums_len = len(nums)
        self.cur_ans = sum(self.blocks)  # 表示当前结果,目的是为了剪枝

    def dfs(self, idx):
        if idx == self.nums_len:
            ans = 0
            for i in range(len(self.blocks)):
                if not self.use[i]:
                    ans += self.blocks[i]
            self.ans = max(self.ans, ans)
            return

        for i in range(len(self.blocks)):
            if self.blocks[i] >= self.nums[idx]:
                if not self.use[i] and self.cur_ans - self.blocks[i] <= self.ans:
                    continue
                pre_state = self.use[i]
                if not pre_state:
                    self.cur_ans -= self.blocks[i]
                self.blocks[i] -= self.nums[idx]
                self.use[i] = True
                self.dfs(idx + 1)
                self.use[i] = pre_state
                self.blocks[i] += self.nums[idx]
                if not pre_state:
                    self.cur_ans += self.blocks[i]

    def solve(self):
        self.dfs(0)
        if self.ans % 1 == 0:
            print(int(self.ans))
        else:
            print(self.ans)


N = int(input())
blocks = []
for i in range(N):
    num, block = [int(x) for x in input().split()]
    for j in range(int(num)):
        blocks.append(block)
M = int(input())
nums = [int(x) for x in input().split()]

print(blocks)
print(nums)

s = Solution(blocks, nums)
s.solve()

Java解法
import java.util.*;

public class Huawei {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = Integer.parseInt(sc.nextLine());
        int[][] input = new int[N][2];
        int total = 0;
        for (int i = 0; i < N; i++) {
            String[] input_pre = sc.nextLine().split(" ");
            input[i][0] = Integer.parseInt(input_pre[0]);
            input[i][1] = Integer.parseInt(input_pre[1]);
            total += input[i][0];
        }
        int[] blocks = new int[total];
        int cur = 0;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < input[i][0]; j++) {
                blocks[cur++] = input[i][1];
            }
        }
        int M = Integer.parseInt(sc.nextLine());
        String[] need_pre = sc.nextLine().split(" ");
        int[] need = new int[M];
        for (int i = 0; i < M; i++) {
            need[i] = Integer.parseInt(need_pre[i]);
        }
        System.out.println(alloc(blocks, need));
    }

    static boolean[] used;
    static int res = -1;
    static int cur_res = 0;

    public static int alloc(int[] blocks, int[] need) {
        for (int i = 0; i < blocks.length; i++) {
            cur_res += blocks[i];
        }
        used = new boolean[blocks.length];
        dfs(0, blocks, need);
        return res;
    }

    public static void dfs(int index, int[] blocks, int[] need) {
        if (index == need.length) {
            int sum = 0;
            for (int i = 0; i < blocks.length; i++) {
                if (!used[i])
                    sum += blocks[i];
            }
            res = Math.max(sum, res);
            return;
        }
        for (int i = 0; i < blocks.length; i++) {
            if (blocks[i] >= need[index]) {
                if (!used[i] && cur_res - blocks[i] <= res)//剪枝
                    continue;
                boolean cur_state = used[i];
                if (!cur_state)
                    cur_res -= blocks[i];//这个内存块要从结果中去除
                blocks[i] -= need[index];
                used[i] = true;
                dfs(index + 1, blocks, need);
                used[i] = cur_state;
                blocks[i] += need[index];
                if (!cur_state)
                    cur_res += blocks[i];
            }
        }
    }
}
第三题

对于两个单调递增整数序列s1, s2, 在其中可能存在这样的子序列 ss1, ss2
对于任意i有(ss1[i+1] – ss1[i]) = (ss2[i+1] – ss2[i]) ,
请找出这些子序列中元素个数最多的子序列。
子序列定义:对于长度为N的序列S,从其中删除n个(0<= n <=N)元素后就得到一个子序列SS
输入描述: 两个单调递增整数序列,单个元素取值范围 -10^9 < ss[i] < 10^9,0 < N <=10000
输出描述: 如果能找到子序列,则第一行输出子序列长度,第二三行输出子序列。
如果有多个满足条件子序列,输出元素最小子序列。 如果找不到子序列,输出0即可。

    示例1
    输入
    1 2 3 4 5
    2 4 6 8
    输出
    3
    1 3 5
    2 4 6
    
    示例2
    输入
    1 2 3 4 5
    2 7 12 17
    输出
    0
    说明 无匹配数组
思路

双重循环来枚举两个序列的起点,再用双指针依次向后扫描。
剪枝:用一个二维布尔数组来维护是否被访问过,如果visited[i][j]被访问过了,就不用考虑分别以i和j为起点的两个数组了。

Python解法:
arr1 = list(map(int, input().strip().split()))
arr2 = list(map(int, input().strip().split()))
beginIndex1 = 0
beginIndex2 = 0
ss1 = []
ss2 = []
flag = [[True for _ in range(len(arr2))] for _ in range(len(arr1))]
for beginIndex1 in range(len(arr1)):
    for beginIndex2 in range(len(arr2)):
        if not flag[beginIndex1][beginIndex2]:
            continue
        newSS1 = [arr1[beginIndex1]]
        newSS2 = [arr2[beginIndex2]]
        index1 = beginIndex1+1
        index2 = beginIndex2+1
        while index1arr2[index2]-arr2[beginIndex2]:
                index2 += 1
            if index2==len(arr2):
                break
            if arr1[index1]-arr1[beginIndex1]==arr2[index2]-arr2[beginIndex2]:
                newSS1.append(arr1[index1])
                newSS2.append(arr2[index2])
                flag[index1][index2] = False
                index1 += 1
                index2 += 1
        if len(newSS1)>len(ss1):
            ss1 = newSS1[:]
            ss2 = newSS2[:]
if len(ss1)<=1:
    print(0)
else:
    print(len(ss1))
    print(' '.join(str(i) for i in ss1))
    print(' '.join(str(i) for i in ss2))
Java解法:
import java.util.*;

public class Huawei {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] arr1_pre = sc.nextLine().split(" ");
        String[] arr2_pre = sc.nextLine().split(" ");
        int[] arr1 = new int[arr1_pre.length];
        int[] arr2 = new int[arr2_pre.length];
        for (int i = 0; i < arr1_pre.length; i++) {
            arr1[i] = Integer.parseInt(arr1_pre[i]);
        }
        for (int i = 0; i < arr2_pre.length; i++) {
            arr2[i] = Integer.parseInt(arr2_pre[i]);
        }
        List> res = LongestCommonSequence(arr1, arr2);
        System.out.println(res);
    }

    public static List> LongestCommonSequence(int[] arr1, int[] arr2) {
        int len1 = arr1.length, len2 = arr2.length;
        boolean visited[][] = new boolean[len1][len2];//用于剪枝
        List res1 = new ArrayList<>();
        List res2 = new ArrayList<>();
        for (int i = 0; i < len1; i++) {
            for (int j = 0; j < len2; j++) {
                if (visited[i][j])
                    continue;
                List temp1 = new ArrayList<>();
                List temp2 = new ArrayList<>();
                temp1.add(arr1[i]);
                temp2.add(arr2[j]);
                int ptr1 = i + 1, ptr2 = j + 1;
                while (ptr1 < len1 && ptr2 < len2) {
                    while (ptr1 < len1 && arr1[ptr1] - arr1[i] < arr2[ptr2] - arr2[j]) {
                        ptr1++;
                    }
                    if (ptr1 == len1)
                        break;
                    if (arr1[ptr1] - arr1[i] == arr2[ptr2] - arr2[j]) {
                        temp1.add(arr1[ptr1]);
                        temp2.add(arr2[ptr2]);
                        ptr1++;
                        ptr2++;
                    }
                    if (ptr1 == len1)
                        break;
                    while (ptr2 < len2 && arr1[ptr1] - arr1[i] > arr2[ptr2] - arr2[j]) {
                        ptr2++;
                    }
                    if (ptr2 == len2)
                        break;
                    if (arr1[ptr1] - arr1[i] == arr2[ptr2] - arr2[j]) {
                        temp1.add(arr1[ptr1]);
                        temp2.add(arr2[ptr2]);
                        visited[ptr1][ptr2] = true;//剪枝
                        ptr1++;
                        ptr2++;
                    }
                }
                if (temp1.size() > res1.size()) {
                    res1 = temp1;
                    res2 = temp2;
                }
            }
        }
        if (res1.size() <= 1) {
            return null;
        }
        List> res = new ArrayList<>();
        res.add(res1);
        res.add(res2);
        return res;
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/271193.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号