• UVA


    /*
      本题借鉴了LRJ在github上放的入门经典的代码库
      
      收获 && 总结:
      1. 双端队列deque
      下面这个博客总结的比较细致
      
      2. fgets函数
      http://www.cnblogs.com/aexin/p/3908003.html
      
      3. 该题最好不要用C++的getline,也不要用string,最好还是用字符串数组 char[][],因为我一开始用它们两时,尽管和LRJ的思路基本一样,还是被判Runtime Error,改了以后又是各种WA,后来改了许久才改对...对于输入格式的处理,还是用fgets比较好(虽然我暂时没有足够的理论依据支持这点)
    */


    //一开始我是用C++写的,但是bug一直找不出来,只能先换C来写一次
    #include <iostream>
    #include <queue>
    #include <cstring>
    #include <cctype>
    #include <cstdlib>
    #include <cstdio>
    #define rep(i, n) for (int i = 0; i < (n); i++)
    using namespace std;
    
    const int maxn = 1e3;
    deque<int> ready;
    queue<int> block;
    int n, quantum, c[5], var[26], ip[maxn];
    bool locked;
    char code[maxn][20];
    //ip[pid] 保存pid程序当前需执行的第一条代码,在code中的下标。最初是记录没个程序第一行代码的位置,带程序开始运行语句以后,没运行一句代码,对应程序的pid++ 
    //所有程序存在code数组 
    
    void run(int pid)
    {
    	int q = quantum;
    	while (q > 0)
    	{
    		char*p = code[ip[pid]];
    		switch (p[2])
    		{
    			case '='://赋值,因为常量给定小于100,只要判断其是否为两位,一位和两位的情况,分开处理即可,用 isdigit函数可简化代码 
    			var[p[0] - 'a'] = isdigit(p[5]) ? (p[4] - '0') * 10 + p[5] - '0' : p[4] - '0';
    			q -= c[0];
    			break;
    			
    			case 'i': //print
    			cout << pid + 1 << ": " << var[p[6] - 'a'] << endl;
    			q -= c[1];
    			break;
    			
    			case 'c': //lock
    			if (locked) 
    			{
    				block.push(pid); return;
    			}
    			locked = true;
    			q -= c[2];
    			break;
    			
    			case 'l': //unlock
    			locked = false;
    			if (!block.empty())
    			{
    				int pid2 = block.front();
    				block.pop();
    				ready.push_front(pid2);
    			}
    			q -= c[3];
    			break;
    			case 'd': //end
    				return;
    		}
    		ip[pid]++;
    	}
    	ready.push_back(pid); //如果程序没有读完,重新进入等待队列,作为队尾 
    }
    
    
    int main()
    {	
    	int t;
    	cin >> t;
    	while(t--)
    	{
    		cin >> n;  rep(i, 5) cin >> c[i]; cin >> quantum;
    		getchar();
    		memset(var, 0, sizeof(var));
    		
    		int line = 0;
    		rep(i, n) //先将n个程序的所有代码读入,保存到code 
    		{ 
    			fgets(code[line++], maxn, stdin);
    			ip[i] = line - 1; 
    			while (code[line - 1][2] != 'd')//不断读取代码,直到读完每组的end 
    			fgets(code[line++], maxn, stdin);
    	
    			ready.push_back(i); //将这个程序压入等待队列			
    		}
    		locked = false;
    		while (!ready.empty())
    		{
    			int tp = ready.front();
    			ready.pop_front();
    			run(tp);
    		}
    		if (t) cout << endl;
    	}
    	return 0;
    }


    //后来实在不甘心自己写的C++版本,一直有个bug找不出来,于是用udebug上的两组数据不断比对,调试、加输出,把可能有错的地方轮流换着修改,最后终于用C++写出了AC代码
    //fgets换为getline以后,就一直出错!!!(hhh,这句好像是我昨天一直RE或者WA时,十分怨念,写下的注释)
    #include <iostream>
    #include <queue>
    #include <string>
    #include <cstring>
    #include <cctype>
    #include <cstdlib>
    #include <fstream>
    #define rep(i, n) for (int i = 0; i < (n); i++)
    //#define debug
    using namespace std;
    
    const int maxn = 1e3;
    deque<int> ready;
    queue<int> block;
    int n, quantum, c[5], var[26], ip[maxn];
    bool locked;
    string code[maxn];
    //ip[pid] 保存pid程序当前需执行的第一条代码,在code中的下标。最初是记录没个程序第一行代码的位置,带程序开始运行语句以后,没运行一句代码,对应程序的pid++ 
    //所有程序存在code数组 
    
    void run(int pid)
    {
    	int q = quantum;
    	while (q > 0)
    	{
    		string p = code[ip[pid]];
    		switch (p[2])
    		{
    			case '=': //赋值,因为常量给定小于100,只要判断其是否为两位,一位和两位的情况,分开处理即可,用 isdigit函数可简化代码 
    			var[p[0] - 'a'] = isdigit(p[5]) ? (p[4] - '0') * 10 + p[5] - '0' : p[4] - '0';
    			q -= c[0];
    			break;
    			
    			case 'i': //print
    			cout << pid + 1 << ": " << var[p[6] - 'a'] << endl;
    			q -= c[1];
    			break;
    			
    			case 'c': //lock
    			if (locked) 
    			{
    				block.push(pid); return;
    			}
    			locked = true;
    			q -= c[2];
    			break;
    			
    			case 'l': //unlock
    			locked = false;
    			if (!block.empty())
    			{
    				int pid2 = block.front();
    				block.pop();
    				ready.push_front(pid2);
    			}
    			q -= c[3];
    			break;
    			case 'd': //end
    				return;
    		}
    		ip[pid]++;
    	}
    	ready.push_back(pid); //如果程序没有读完,重新进入等待队列,作为队尾 
    }
    
    int main()
    {
    	#ifdef debug
    	freopen("E:\in.txt", "r", stdin);
    	freopen("E:\out.txt", "w", stdout);
    	#endif
    	cin.tie(0);
    	cin.sync_with_stdio(false);
    	int t;
    	cin >> t;
    	string temp;
    	while (t--)
    	{
    	//	getline(cin, temp);
    		cin >> n;  rep(i, 5) cin >> c[i]; cin >> quantum;
    		getline(cin, temp);
    	//	getchar();
    		memset(var, 0, sizeof(var));
    		
    		int line = 0;
    		rep(i, n) //先将n个程序的所有代码读入,保存到code 
    		{ 
    			getline(cin, code[line++]);
    		//	cout << "test: " << code[line - 1] << endl;;
    			ip[i] = line - 1; 
    			while (code[line - 1] != "end") //不断读取代码,直到读完每组的end 
    			{
    				getline(cin, code[line++]);
    		//		cout << "test: " << code[line - 1] << endl;
    			}
    			
    			ready.push_back(i); //将这个程序压入等待队列 			
    		}
    		
    		locked = false;
    		while (!ready.empty())
    		{
    			int tp = ready.front();
    			ready.pop_front();
    			run(tp);
    		}
    		if (t) cout << endl;
    	}
    	#ifdef debug
    	fclose(stdin);
    	fclose(stdout);
    	#endif
    	return 0;
    }


  • 相关阅读:
    DotNetty 实现 Modbus TCP 系列 (一) 报文类
    C# 获取文件详细备注信息 (如图片、视频实际创建时间)
    Java 下载 HLS (m3u8) 视频
    开源 DotNetty 实现的 Modbus TCP/IP 协议
    SQL Server 2008 开启远程连接
    在 Web 页面使用 VLC 插件播放 m3u8 视频流 (360 极速模式)
    在 Web 页面中使用离线地图
    使用 Travis CI 自动部署 Hexo 站点至 GitHub Pages
    BZOJ 3238: [Ahoi2013]差异((单调栈+后缀数组)/(后缀树))
    BZOJ 3998: [TJOI2015]弦论(后缀自动机)
  • 原文地址:https://www.cnblogs.com/mofushaohua/p/7789408.html
Copyright © 2020-2023  润新知