zoukankan      html  css  js  c++  java
  • 并行程序模拟Uva 210

    这个题满满的都是套路。其实根本不难,就是一个双向队列的问题。如果你只看了紫书的话,那么你完蛋了,因为这个紫书数条件给的不够。你需要去看原题,并且要把它完整地翻译过来。

    • 这个题是有多个输入的,这个一般中文翻译都没有,需要去看原题。

    • 时间片用完之后,如果正在执行语句,那么这个语句将继续执行下去,哪怕最后时间为负数。并不是说时间一到就不执行了

    • 输入的时候首先要告诉你有几个输入,随后空一行。然后开始正式的一个输入块;输入块完成后,再空一行开始另一个输入块,循环往复。

    • 输出时每个输入块对应一个输出块,然后空一行再开始另一个输出块。最后一个输出块不用空最后一行。

    思路

    按照操作系统的做法:设计一个就绪队列,一个阻塞队列还有一个运行队列。在使用Java的双端队列API,整个题就非常的简单了。

    package com.ahyer;
    
    import java.util.*;
    
    public class Main {
        static List<Program> list = new ArrayList<>();
        static Deque<Program> runState = new LinkedList<>();
        static Deque<Program> prepareState = new LinkedList<>();
        static Deque<Program> blockState = new LinkedList<>();
        static Map<String, String> map = new HashMap<>();
        static boolean block = false;
    
        static class Program {
            Deque<Statement> deque = new ArrayDeque<>();
            int programID;
        }
    
        static class Statement {
            String statement;
            int remain;
            int id;
        }
    
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            String s = scanner.nextLine();
            int per = Integer.parseInt(s);
            while (per-- != 0) {
                list.clear();
                blockState.clear();
                runState.clear();
                prepareState.clear();
                map.clear();
                scanner.nextLine();
                String s1 = scanner.nextLine();
                String[] s2 = s1.split(" ");
                int program = Integer.parseInt(s2[0]);
                int t1 = Integer.parseInt(s2[1]);
                int t2 = Integer.parseInt(s2[2]);
                int t3 = Integer.parseInt(s2[3]);
                int t4 = Integer.parseInt(s2[4]);
                int t5 = Integer.parseInt(s2[5]);
                int Q = Integer.parseInt(s2[6]);
                for (int i = 0; i < program; i++) {
                    list.add(new Program());
                }
                int programeNums = 0;
    
                while (programeNums != program) {
                    String s3 = scanner.nextLine();
                    if (s3.equals("")) break;
                    Statement statement = new Statement();
                    list.get(programeNums).deque.addLast(statement);
                    list.get(programeNums).programID = programeNums + 1;
                    statement.statement = s3;
                    if (s3.contains("=")) {
                        statement.id = 1;
                        statement.remain = t1;
                    } else if (s3.contains("print")) {
                        statement.id = 2;
                        statement.remain = t2;
                    } else if (s3.equals("lock")) {
                        statement.remain = t3;
                        statement.id = 3;
                    } else if (s3.equals("unlock")) {
                        statement.remain = t4;
                        statement.id = 4;
                    } else {
                        statement.remain = t5;
                        statement.id = 5;
                        prepareState.addLast(list.get(programeNums++));
                    }
                }
                //输入完成了
    
                while (!prepareState.isEmpty() || !blockState.isEmpty() || !runState.isEmpty()) {
                    if (!prepareState.isEmpty()) {
                        runState.addFirst(prepareState.removeFirst());
                    }
                    Program runProgram = runState.getFirst();
                    int time = Q;
                    while (time > 0) {
                        int remain = runProgram.deque.getFirst().remain;
                        if (solve(runProgram)) {
                            break;
                        }
                        time -= remain;
                    }
                    if (!runState.isEmpty()) {
                        prepareState.addLast(runState.removeFirst());
                    }
                }
                if (per != 0) {
                    System.out.println();
                }
            }
        }
    
        private static boolean solve(Program runProgram) {
            String statement = runProgram.deque.getFirst().statement;
            String[] split = null;
            //程序代码序列
            if (runProgram.deque.getFirst().id == 3 && block) {
                blockState.addLast(runState.removeFirst());
                return true;
            }
            switch (runProgram.deque.removeFirst().id) {
                case 1:
                    split = statement.split(" ");
                    map.put(split[0], split[2]);
                    break;
                case 2:
                    split = statement.split(" ");
                    if (map.get(split[1]) == null) {
                        map.put(split[1], "0");
                    }
                    System.out.println(runProgram.programID + ": " + map.get(split[1]));
                    break;
                case 3:
                    block = true;
                    break;
                case 4:
                    block = false;
                    if (!blockState.isEmpty()) {
                        prepareState.addFirst(blockState.removeFirst());
                    }
                    break;
                case 5:
                    //本程序结束了
                    runState.removeFirst();
                    return true;
                default:
                    break;
            }
            return false;
        }
    }
    
    

    这个双端队列的API。最好分开写,因为如果单独写的话,如果这个队列只有一个元素,那么你连着写remove()掉再addLast()那就相当于没有变。上面这个代码不存在这种问题,因为操作多个队列。

  • 相关阅读:
    将WinServers2019打造成家用系统
    WindowsServers2019上手体验
    【代码模板】不存在的NOIP2017
    NOIP2018初赛翻车总结
    【初赛】各种排序算法总结
    【Luogu1996】约瑟夫问题(模拟,解法汇总)
    【初赛】NOIP2018程序模板
    MongoDB
    非关系型数据库----MongoDB
    用Python来操作redis 以及在Django中使用redis
  • 原文地址:https://www.cnblogs.com/HyPhoenix/p/14407377.html
Copyright © 2011-2022 走看看