分布式队列 - 蓝桥杯2024年第十五届省赛真题

基础知识要求:

Java:方法、集合、泛型、数组、for循环、switch case语句、逻辑运算符、if判断、权限修饰符、static关键字、Scanner类
Python: 方法、列表、for循环、逻辑运算符、if判断、input()

题目:

小蓝最近学习了一种神奇的队列:分布式队列。简单来说,分布式队列包含 N 个节点(编号为 0 至 N − 1,其中 0 号为主节点),其中只有一个主节点,其余为副节点。主/副节点中都各自维护着一个队列,当往分布式队列中添加元素时都是由主节点完成的(每次都会添加元素到队列尾部);副节点只负责同步主节点中的队列。可以认为主/副节点中的队列是一个长度无限的一维数组,下标为 0, 1, 2, 3 . . . ,同时副节点中的元素的同步顺序和主节点中的元素添加顺序保持一致。

由于副本的同步速度各异,因此为了保障数据的一致性,元素添加到主节点后,需要同步到所有的副节点后,才具有可见性。

给出一个分布式队列的运行状态,所有的操作都按输入顺序执行。你需要回答在某个时刻,队列中有多少个元素具有可见性。

输入格式

第一行包含一个整数 N,表示节点个数。接下来包含多行输入,每一行包含一个操作,操作类型共有以下三种:add、sync 和 query,各自的输入格式如下:

  1. add element:表示这是一个添加操作,将元素 element 添加到队列中;

  2. sync follower_id:表示这是一个同步操作,follower_id 号副节点会从主节点中同步下一个自己缺失的元素;

  3. query:查询操作,询问当前分布式队列中有多少个元素具有可见性。

输出格式

对于每一个 query 操作,输出一行,包含一个整数表示答案。

样例输入

复制代码
3
add 1
add 2
query
add 1
sync 1
sync 1
sync 2
query
sync 1
query
sync 2
sync 2
sync 1
query

样例输出

复制代码
0
1
1
3

【样例说明】

执行到第一个 query 时,队列内容如下:

0:[1,2]

1:[]

2:[]

两个副节点中都无元素,因此答案为 0。

执行到第二个 query 时,队列内容如下:

0:[1,2,1]

1:[1,2]

2:[1]

只有下标为 0 的元素被所有节点同步,因此答案为 1。执行到第三个 query 时,队列内容如下:0:[1,2,1]1:[1,2,1]2:[1]

只有下标为 0 的元素被所有节点同步,因此答案为 1。执行到第四个 query 时,队列内容如下:0:[1,2,1]1:[1,2,1]2:[1,2,1]

三个元素都被所有节点同步,因此答案为 3。

【评测用例规模与约定】

对于 30% 的评测用例:1 ≤ 输入的操作数 ≤ 100。

对于 100% 的评测用例:1 ≤ 输入的操作数 ≤ 2000,1 ≤ N ≤ 10,1 ≤f ollower_id < N,0 ≤ element ≤ 105。

思路解析:

为了解决这个问题,我们可以使用一个数组来跟踪每个副节点当前同步到的队列位置。同时,我们需要记录主节点队列的当前长度。对于每一个操作,我们可以根据操作类型来更新这些信息。

Java代码示例:

java 复制代码
import java.util.ArrayList;  
import java.util.List;  
import java.util.Scanner;  
  
public class NodeSync {  
  
    public static void main(String[] args) {  
        Scanner scanner = new Scanner(System.in);  
        System.out.print("请输入节点总数(包括主节点和副节点):");  
        int N = scanner.nextInt();  
  
        List<Integer> mainQueue = new ArrayList<>(); // 主节点队列  
        int[] followerSync = new int[N - 1]; // 跟踪每个副节点同步到的位置(不包括主节点)  
  
        List<String> operations = new ArrayList<>();  
        // 这里假设operations已经以某种方式填充了  
        // operations.add("add 1");  
        // operations.add("add 2");  
        // ...  
  
        // 示例操作,硬编码到程序中  
        operations.add("add 1");  
        operations.add("add 2");  
        operations.add("query");  
        operations.add("add 1");  
        operations.add("sync 1");  
        operations.add("sync 1");  
        operations.add("sync 2");  
        operations.add("query");  
        operations.add("sync 1");  
        operations.add("query");  
        operations.add("sync 2");  
        operations.add("sync 2");  
        operations.add("sync 1");  
        operations.add("query");  
  
        processOperations(operations, N, mainQueue, followerSync);  
  
        scanner.close();  
    }  
  
    private static void processOperations(List<String> operations, int N, List<Integer> mainQueue, int[] followerSync) {  
        for (String operation : operations) {  
            String[] parts = operation.split(" ");  
            String op = parts[0];  
  
            switch (op) {  
                case "add":  
                    int element = Integer.parseInt(parts[1]);  
                    addElement(mainQueue, element);  
                    break;  
                case "sync":  
                    int followerId = Integer.parseInt(parts[1]);  
                    syncFollower(followerId, N, mainQueue, followerSync);  
                    break;  
                case "query":  
                    System.out.println(queryVisibility(mainQueue, followerSync));  
                    break;  
                default:  
                    System.out.println("无效的操作:" + op);  
            }  
        }  
    }  
  
    private static void addElement(List<Integer> mainQueue, int element) {  
        mainQueue.add(element);  
    }  
  
    private static void syncFollower(int followerId, int N, List<Integer> mainQueue, int[] followerSync) {  
        if (followerId >= 0 && followerId < N - 1 && followerSync[followerId] < mainQueue.size()) {  
            followerSync[followerId]++;  
        }  
    }  
  
    private static int queryVisibility(List<Integer> mainQueue, int[] followerSync) {  
        int minSync = Integer.MAX_VALUE;  
        for (int sync : followerSync) {  
            minSync = Math.min(minSync, sync);  
        }  
        return Math.min(minSync, mainQueue.size());  
    }  
}

Python代码示例:

python 复制代码
def process_operations(operations, N):  
    main_queue = []  # 主节点队列  
    follower_sync = [0] * (N - 1)  # 跟踪每个副节点同步到的位置(不包括主节点)  
  
    def add_element(element):  
        main_queue.append(element)  
  
    def sync_follower(follower_id):  
        if 0 <= follower_id < N - 1 and follower_sync[follower_id] < len(main_queue):  
            follower_sync[follower_id] += 1  
  
    def query_visibility():  
        # 查找所有副节点中最小的同步位置  
        min_sync = min(follower_sync)  
        # 具有可见性的元素是主节点队列中从下标0到min_sync-1的元素  
        return min(min_sync, len(main_queue))  
  
    for operation in operations:  
        op, *args = operation.split()  
        if op == 'add':  
            element = int(args[0])  
            add_element(element)  
        elif op == 'sync':  
            follower_id = int(args[0])  
            sync_follower(follower_id)  
        elif op == 'query':  
            print(query_visibility())  
  
# 从用户输入中获取N的值  
N = int(input("请输入节点总数(包括主节点和副节点):"))  
  
# 假设operations是从某个输入源读取的,这里用字符串列表代替  
operations = [  
    "add 1",  
    "add 2",  
    "query",  
    "add 1",  
    "sync 1",  
    "sync 1",  
    "sync 2",  
    "query",  
    "sync 1",  
    "query",  
    "sync 2",  
    "sync 2",  
    "sync 1",  
    "query"  
]  
  
# 调用函数处理操作  
process_operations(operations, N)
相关推荐
无心水28 分钟前
【分布式利器:腾讯TSF】10、TSF故障排查与架构评审实战:Java架构师从救火到防火的生产哲学
java·人工智能·分布式·架构·限流·分布式利器·腾讯tsf
我的xiaodoujiao2 小时前
使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 38--Allure 测试报告
python·学习·测试工具·pytest
燃于AC之乐2 小时前
我的算法修炼之路--4 ———我和算法的爱恨情仇
算法·前缀和·贪心算法·背包问题·洛谷
Boilermaker19928 小时前
[Java 并发编程] Synchronized 锁升级
java·开发语言
沈浩(种子思维作者)8 小时前
真的能精准医疗吗?癌症能提前发现吗?
人工智能·python·网络安全·健康医疗·量子计算
Cherry的跨界思维8 小时前
28、AI测试环境搭建与全栈工具实战:从本地到云平台的完整指南
java·人工智能·vue3·ai测试·ai全栈·测试全栈·ai测试全栈
MM_MS8 小时前
Halcon变量控制类型、数据类型转换、字符串格式化、元组操作
开发语言·人工智能·深度学习·算法·目标检测·计算机视觉·视觉检测
独自破碎E8 小时前
【二分法】寻找峰值
算法
njsgcs9 小时前
ue python二次开发启动教程+ 导入fbx到指定文件夹
开发语言·python·unreal engine·ue
alonewolf_999 小时前
JDK17新特性全面解析:从语法革新到模块化革命
java·开发语言·jvm·jdk