【日常学习】【双端队列】 Uva - 210 Concurrency Simulator题解

ruka也的确是个小恶魔一般的东西,双端队列竟然只提了一句让我们自己去查TUT比人痛心疾首学习了众多网上神犇们的文章,终于知道了个大概。有几篇整理得非常精妙的文章,在这里给大家分享一下。

http://blog.163.com/zhoumhan_0351/blog/static/399542272010358491361/这篇文章相对有些生硬,但是基本系统的介绍了一下双端队列。

http://hi.baidu.com/xuehuo_0411/item/f72d5120d5006ad0a517b6b8这篇用例子介绍了一下, 和上一篇基本没什么区别。


http://www.cnblogs.com/silence250627170/archive/2011/07/24/2115692.html在这里我要强烈推荐的是这篇文章,整合了其他几篇文章的内容,详实周到,非常有用,其中也很好的总结了vector,list和deque的优势和不足。


那么我自己来简单总结一下双端队列deque的应用:

1.创建时,和其他容器一样的格式,如deque<int> a; 也可以限定元素个数和内容,详细见上述网页;注意要使用头文件deque

2.常用函数:

a.push_front() a.push_back() a.pop_front() a.pop_back()从队首或队尾入队或出队

3.除了正向的iterator,还可反向遍历deque双端队列中元素迭代器: 
(1)reverse_iterator rbegin() 注意是rbegin 此时迭代器默认指向队尾,使用it++实际上是向前移动
(2)reverse_iterator rend()   

接下来是这次的例题Concurrency Simulator 并行程序模拟

题目来源:ACM-ICPC World Finals 1991 - San Antonio;Uva-210

这道例题说实话有些惭愧,刚开始并不能完全理解,也不知从何下手,读了本站Devin老师的程序,才明白怎么回事。

这个程序给我的意外惊喜是,原来i/o/iostream头文件里已经包含了string头文件内容 我不太明白这是怎么回事 有知道的大大请解释一下

二话不说上代码 

#include<iostream>//里面包含string及其函数
#include<deque>
#include<cstring>
using namespace std;

deque<int> ready,block;
int var[26],id[1024],st[5],program,q,t,i;//关于这一段请看下面
string code[1024];//存储指令内容
bool locked;

void run(int i){
	int time=q;
	while (time>0){
		string now=code[id[i]];
		if(now[2] == '='){  
            var[now[0] - 'a'] = isdigit(now[5]) ? (now[4]-'0')*10+(now[5]-'0') : now[4]-'0';  //isdigit检查是否为数字,var依次存储a,b,c等变量当前值
            time -= st[0];  
        }  
        else if(now[2] == 'i'){  
            cout<<i+1<<": "<<var[now[6]-'a']<<endl;  
            time -= st[1];  
        }  
        else if(now[2] == 'c'){  
            if(locked){block.push_back(i);return;}  
            locked = true;  
            time -= st[2];  
        }  
        else if(now[2] == 'l'){  
            if(!block.empty()) ready.push_front(block.front()),block.pop_front();   
            time -= st[3];  
            locked = false;  
        }  
        else if(now[2] == 'd'){return ;}  
        id[i]++;  
    }  
    ready.push_back(i);
}

int main(){
	cin>>t;
	while (t--){
		cin>>program>>st[0]>>st[1]>>st[2]>>st[3]>>st[4]>>q;
		memset(var,0,sizeof(var));  
        ready.clear();block.clear();  
        int line_num = 0;
		for (i=0;i<program;i++){
			ready.push_back(i);
			getline(cin,code[line_num++]);
			id[i]=line_num-1;
			while (code[line_num-1]!="end"){
				getline(cin,code[line_num++]);
			} 
		}
		locked=false;
		while (!ready.empty()){
			int now=ready.front();ready.pop_front();
			run(now);
		}
		if(t) cout<<endl;
	}
	return 0;
} 

程序是简单的模拟,更多的注释我写在了Devin老师的程序里

int main(){  //ready是排队队列,里面存着每个程序的序号,block是阻止队列,同样存着每个程序序号 
    freopen("1.txt","r",stdin);
	freopen("2.txt","w",stdout); 
    int T;  //code是指令数组字符串类型,全部程序依次排列,id存储的是每个程序(的序号)对应的第一个指令序号,指令序号在code里 
    cin>>T;  
    while(T--){  
        scanf("%d%d%d%d%d%d%d",&program,&ans[0],&ans[1],&ans[2],&ans[3],&ans[4],&Q);  
        memset(var,0,sizeof(var));  
        ready.clear();block.clear();  
        int line_num = 0;//cin.get(); 好像没意义 //一组数据中全程都用一个line_num不清零 
        for(int i = 0; i < program ;i++){//可能有很多组数据,每个数据有很多个程序,每个程序有很多个指令。T是数据组数,program是程序数,Q是额定时间  
            ready.push_back(i);  // 对于每组数据的每个程序,首先将程序序号压入队尾 
            getline(cin,code[line_num++]);  //读入第一个指令,放到 code中第line_num个位置,并将line_num加一 
            id[i] = line_num-1;  //第0个程序的id是该程序第一个指令在code中的编号 line_num-1今后称“原指令序号” 
            while(code[line_num-1]!="end")  //原指令序号对应的指令不为end时 
                getline(cin,code[line_num++]);//读入新指令,并将num_line加一,其他不变,只变指令数组  
        }  
        Lock = false;  
        while(!ready.empty()){  
            int now = ready.front();ready.pop_front(); //如果排队队列不为空,就让now等于排队队列中第一个程序序号,同时出队 
            run_program(now);  //运行 
        }  
        if(T)cout<<endl;  //还有其他几组数据就输出空格 
    }  
    return 0;  

notepad++可真是个好东西,能把乱码的汉字变成可以显示的O(∩_∩)O~

原程序中的cin.get好像没有意义啊,有谁能解释一下?


——白日射金阙,虎豹九关开

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值