紫书第六章例6-1:Concurrency Simulator(UVA210)

传送门
写这道题的时候表示看了很久都没看懂到底是什么意思。。最后还是看了大佬的题解才明白题意http://blog.csdn.net/qq_40738840/article/details/104271115

在我研究了很久大佬的代码后我终于看懂题意
题目大概意思就是:
要我们来模拟并行,即只能有一个运行态其余都是等待状态
输入n个程序,每个程序有一些指令,指令分为五种,每种程序都要花相应的时间,一个程序在运行态的时候他执行所有指令所花的时间不能超过Q即配额。如果遇到block时别的程序已经执行过block,那么该程序就进入阻塞队列,不会执行下面的语句,直到遇到unlock才会将阻塞态队首放入等待态队首,然后按照样例模拟一下就明白了。
这里再解释一下样例(题目要求的是多组样例,但测试样例并没有体现这一点,所以在写代码的时候要注意)

3 1 1 1 1 1 1
a = 4
print a
lock
b = 9
print b
unlock
print b
end
a = 3
print a
lock
b = 8
print b
unlock
print b
end
b = 5
a = 17
print a
print b
lock
b = 21
print b
unlock
print 

由于总配额是1,而五条指令所花的时间也是1,那么就是说每个程序每次只能执行一条语句,如果遇到block之前已经有程序执行过block那么就直接跳出执行下一个程序,所以说刚开始的时候执行程序的顺序是1 2 3,第一轮结束a = 3,所以在第二轮运行的时候输出a为3,依次类推,如果还看不懂的话就看代码和注释吧。
这道题就是采用双端队列与队列的结合,首先定义三个队列

queue<string>q1[a[0]];//每个程序的所有指令
queue<int>qb;//阻塞队列
deque<int>qr;//等待队列

这里的a[0]表示有n个程序,第i个程序的所有指令都放入该程序的队列中。

注意我们要设置两个标记:
1.isblock:标记是否遇到过block,如果没有遇到过就设置为false,如果遇到过就设置为true,将该程序插入阻塞队列
2.isBlock:标记这个程序是否被阻塞,如果block为true就把isBlock标记为true,否则为false
那么如果isBlock为false并且该程序的指令还没有执行完,那么我们就还要将该程序放入等待队列队首。

同时在访问前要判断队列是否为空,格式也有一定要求,每个样例后面都要有一个空行。

完整代码及注释:

#include <iostream>
#include <queue>
#include <deque>
#include <string>
#include <cstring>
#include <map>
using namespace std;
int a[7];//每个样例输入的七个数,分别代表n个程序,t1-t5指令所花时间,每个运行态的配额Q
string s;//存储指令
string ans;//存储变量值
int main()
{
    int T;//测试样例个数
    cin >> T;
    for(int j = 0 ; j < T; j++)
    {
        for(int i = 0 ; i < 7; i++)
        {
            cin >> a[i];
        }
        getchar();
        queue<string>q1[a[0]];//每个程序的所有指令
        queue<int>qb;//阻塞队列
        deque<int>qr;//等待队列
        for(int i = 0 ; i < a[0]; i++)//输入n个程序的指令
        {
            while(getline(cin,s) && s != "end")//第i个程序的指令
            {
                q1[i].push(s);
            }
            qr.push_back(i);//插入等待队列
        }
        if(j != 0)
        {
            cout << endl;
        }
        map<string,string>mp;//存储赋值操作语句
        bool isblock = false;//标记是否有锁
        while(!qr.empty())//等待队列不为空
        {
            int t = 0;//程序执行的时间
            int k = qr.front();//取出等待队列队首,执行队首程序
            qr.pop_front();
            bool isBlock = false;//标记是否发生阻塞
            while(t < a[6]/*该程序未超时*/ && !q1[k].empty()/*该程序未执行完*/)
            {
                s = q1[k].front();//取出指令
                int i = s.find('=');
                if(i != string::npos)//如果是赋值指令
                {
                    mp[s.substr(0,i - 1)] = s.substr(i + 2);//赋值
                    t += a[1];//计时
                }
                else//如果不是赋值操作
                {
                    i = s.find(' ');
                    if(i != string::npos)//打印输出
                    {
                        ans = "0";
                        if(mp[s.substr(i + 1)] != "")//如果该字母的值不为空
                        {
                            ans = mp[s.substr(i + 1)];
                        }
                        t += a[2];
                        cout << k + 1 << ": " << ans.c_str() << endl;
                    }
                    else //如果遇到阻塞
                    {
                        if(s[0] == 'l')
                        {
                            if(!isblock)//如果之前没有遇到过阻塞
                            {
                                isblock = true;
                                t += a[3];
                            }
                            else//如果之前遇到过
                            {
                                qb.push(k);//放入阻塞队列队尾
                                isBlock = true;
                                break;
                            }
                        }
                        else if(s[0] == 'u')//遇到解锁
                        {
                            isblock = false;//解锁
                            if(!qb.empty())//如果阻塞队列非空
                            {
                                qr.push_front(qb.front());//阻塞队列队首插入等待队列队首
                                qb.pop();
                            }
                            t += a[4];
                        }
                    }
                }
                q1[k].pop();
            }
            if(!q1[k].empty() && !isBlock)
            {
                qr.push_back(k);//如果非空再次加入队列尾部
            }
        }
    }
    return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
我想将frontend 也是用volumes,将其映射到/app/frontend目录,在/app/frontend下install以及build,如何实现 docker-compose.yml文件: version: '3' services: frontend: build: context: ./frontend dockerfile: Dockerfile ports: - 8010:80 restart: always backend: build: context: ./backend dockerfile: Dockerfile volumes: - /app/backend:/app environment: - CELERY_BROKER_URL=redis://redis:6379/0 command: python manage.py runserver 0.0.0.0:8000 ports: - 8011:8000 restart: always celery-worker: build: context: ./backend dockerfile: Dockerfile volumes: - /app/backend:/app environment: - CELERY_BROKER_URL=redis://redis:6379/0 command: celery -A server worker -l info --pool=solo --concurrency=1 depends_on: - redis - backend restart: always celery-beat: build: context: ./backend dockerfile: Dockerfile volumes: - /app/backend:/app environment: - CELERY_BROKER_URL=redis://redis:6379/0 command: celery -A server beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler depends_on: - redis - backend restart: always redis: image: redis:latest ports: - 6379:6379 restart: always mysql: image: mysql:latest environment: - MYSQL_ROOT_PASSWORD=sacfxSql258147@ ports: - 8016:3306 volumes: - ./mysql:/var/lib/mysql restart: always frontend:dockerfile文件 FROM node:16.18.1 WORKDIR /app/frontend COPY package*.json ./ RUN npm install COPY . . RUN npm run build:prod FROM nginx:latest COPY --from=0 /app/frontend/dist/ /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
07-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值