分布式队列 - 蓝桥杯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)
相关推荐
武昌库里写JAVA1 分钟前
iView Admin的side menu改为top menu
java·vue.js·spring boot·课程设计·宠物管理
开开心心就好5 分钟前
快速搜索与管理PDF文档的专业工具
java·运维·windows·pdf·自动化·excel·音视频
大模型铲屎官6 分钟前
【深度学习-Day 2】图解线性代数:从标量到张量,理解深度学习的数据表示与运算
人工智能·pytorch·python·深度学习·线性代数·机器学习·llm
a181001_34 分钟前
python下载
开发语言·后端·python·青少年编程
蹦蹦跳跳真可爱58938 分钟前
Python----卷积神经网络(LeNet-5的手写体识别)
人工智能·python·深度学习·神经网络·cnn
BillKu40 分钟前
前端Vue3 + 后端Spring Boot,前端取消请求后端处理逻辑分析
java·vue.js·spring boot
Chan161 小时前
Redis从入门到实战实战篇2
java·数据库·redis·spring·lua
qq_447429411 小时前
数据结构与算法:图论——并查集
数据结构·算法·图论
兮山与1 小时前
数据结构4.0
java·开发语言·数据结构
MarsBighead2 小时前
openGauss DB4AI与scikit-learn模块对比探究
人工智能·python·scikit-learn·opengauss·db4ai