首页 > 其他分享 >洛谷 P9518 queue

洛谷 P9518 queue

时间:2023-09-14 20:58:54浏览次数:109  
标签:p1 洛谷 puts ++ P9518 queue while && Error

一眼模拟。

需要维护的东西可以根据操作求得:

  • start:正在玩游戏的 \(1\) 或 \(2\) 个人;
  • arrive:当前在排队但没玩游戏的队列、每个人是否在排队、游玩;
  • leave:每个人是否在排队、游玩。

如何维护

正在玩游戏的人

我们使用 \(p_1\)、\(p_2\) 两变量存储,优先保证 \(p_1\) 有值,当 \(p_1\) 为空时上一轮无人游玩,\(p_2\) 为空时上一轮仅有一人游玩。

tips:由于优先保证 \(p_1\) 有值,故 \(p_2\) 为空时 \(p_1\) 非空。


当前在排队但没玩游戏的队列

用数组模拟队列并惰性删除即可。

tips:将正在玩游戏的人放到队首,并在玩完游戏后将其放到队尾,只用维护一个“队列”即可。


每个人是否在排队、游玩

map 映射名字到队列中的位置即可(tips:为什么不映射 bool,在这个讨论帖里说的已经很明白了)。

要定义的东西如下:

const int Maxn = 1e6 + 7;
int Q, l = 1, r = 1, len;
string q[Maxn], p1, p2;
map <string, int> m;

操作中的细节

start

只要队列里有人,游戏就能进行。因为根据题意描述,若只有 A 在游戏且无人排队、A 可在结束游戏后成为队首并加入下一轮游戏,故队列无人时输出 Error

否则,将上一轮游玩的人放回队尾,并取出这一轮游玩的人(\(\geq 1\),想一想,为什么),将其名字输出。

具体实现如下:

if(opt == "start") {
	p1 = p2 = "";
	while(l < r && len) {
	    while(l < r && m[q[l]] != l) ++l;
	    if(l < r)
	    	m[q[l]] = r, q[r++] = q[l], ++l;
	    --len;
	}

	while(l < r && m[q[l]] != l)
		++l;
	if(l == r) {
		puts("Error");
		continue;
	}
	p1 = q[l]; 
    cout << p1;
	++len;
	   
	int pos = l + 1;
    while(pos < r && m[q[pos]] != pos) 
		++pos;
    if(pos < r) 
		p2 = q[pos], cout << ' ' << p2, ++len;
    puts("");
}

arrive

没什么好说的,看代码:

if(opt == "arrive") {
	cin >> t;
	if(m[t]) 
		puts("Error");
	else 
		q[r++] = t, m[t] = r - 1, puts("OK"); 
}

leave

x 在队列里且 x 不为玩家,x 可以离队;否则不能。

if (opt == "leave") {
	cin >> t;
	if(m[t] && t != p1 && t != p2) 
		m[t] = 0, puts("OK");
	else 
		puts("Error");
}

Warning

考场并没有卡暴力 \(O(n)\) 删除的做法,但考试结束后同机房的 @幻想繁星 就申请加了 hack 数据(试图卡掉时的讨论帖hack 数据

Talk is cheap, show you the code.

#include <bits/stdc++.h>

using namespace std;
const int Maxn = 1e6 + 7;

int Q, l = 1, r = 1, len;
string q[Maxn], p1, p2;
map <string, int> m;

int main() {
	ios::sync_with_stdio(false); cin.tie(0), cout.tie(0);
	cin >> Q;
	string opt, t;
	while(Q--) {
		cin >> opt;
		if(opt == "start") {
			p1 = p2 = "";
            while(l < r && len) {
                while(l < r && m[q[l]] != l) ++l;
                if(l < r)
                	m[q[l]] = r, q[r++] = q[l], ++l;
                --len;
            }

            while(l < r && m[q[l]] != l)
				++l;
            if(l == r) {
				puts("Error");
				continue;
			}
			p1 = q[l]; 
            cout << p1;
			++len;
            
			int pos = l + 1;
            while(pos < r && m[q[pos]] != pos) 
				++pos;
            if(pos < r) 
				p2 = q[pos], cout << ' ' << p2, ++len;
            puts("");
		}
		else if(opt == "arrive") {
			cin >> t;
			if(m[t]) 
				puts("Error");
			else 
				q[r++] = t, m[t] = r - 1, puts("OK"); 
		}
		else {
			cin >> t;
			if(p1 == t || p2 == t || !m[t]) 
				puts("Error");
			else 
				m[t] = 0, puts("OK");
		}
	}
	
	return 0;
}

标签:p1,洛谷,puts,++,P9518,queue,while,&&,Error
From: https://www.cnblogs.com/Hszzzx/p/17703405.html

相关文章

  • 洛谷OJ [P5018 对称二叉树] (深度优先搜索、二叉树、思维)
    P5018[NOIP2018普及组]对称二叉树题意:给定一棵树,树上的每个结点有一个权值,问你这棵树的子树中节点数最多的对称二叉树的节点数是多少?对称二叉树的定义如下:对于树中的每一个结点,要么没有子节点,要么既有左儿子,又有右节点,且对称位置的结点点权相等。输入格式:第一行......
  • 安装系统出现dracut-initqueue timeout
    dracut-initqueuetimeout因为系统安装的时候默认的读取不到U盘的数据,需要手动指定。两种解决办法:出来install的界面之后,按e进入编辑界面,将原来第一行的内容改成:vmlinuzinitrd=initrd.imglinuxddnomodesetquiet第二行不变,然后ctrl+x执行,执行完之后能看到电脑所有的硬......
  • 【dfs基础题】洛谷P1219题解
    题目大意给定棋盘的规格为\(n×n\),现在要摆\(n\)个皇后,使得每个皇后不能互相攻击。题目解答由题意可知,如果两个皇后在同一行或同一列或同一对角线,那么就会互相攻击。那么就简单了,若当前要摆的是第\(i\)个皇后,那么只需要for循环一遍前面的\(i-1\)个皇后,判断前面的皇后......
  • 队列(Queue)
    一、队列的概念队列是一个先进先出的数据结构。联想一下链表,在单链表中,只能对表尾进行插入,对表头进行结点的删除,这样强限制性的链表,就是所说的队列。也就是说,队列是限定在表的一端进行插入,表的另一端进行删除的数据结构。如图去买票排队,每一列队伍都有一个队尾和队首,先来的先买......
  • 洛谷[P1305 新二叉树] Tag:二叉树、基础数据结构
    P1305新二叉树题目描述:输入一串二叉树,输出其前序遍历。输入格式:第一行为二叉树的节点数$n(1\len\le26)$,后面\(n\)行,每一个字母为节点,后两个字母分别为其左右儿子。特别地,数据保证第一行读入的节点必为根节点。空节点用*表示输出格式:二叉树的前序遍历。思路:对......
  • Java多线程____BlockingQueue阻塞队列使用
    packagecom.frame.base.thread;importjava.util.concurrent.BlockingQueue;importjava.util.concurrent.ArrayBlockingQueue;/***并发编程____阻塞队列*/publicclassBlockingQueueTest{ publicstaticvoidmain(String[]args)throwsInterruptedException{......
  • 洛谷 CF707C Pythagorean Triples の 题解
    这道题是一道数论题,不可用暴力通过,因为输入范围极大,基本上循环是不能在这道题上使用的了。前面大佬们讲的我听不懂,于是在教练的帮助下,我利用题面给出的多组样例找到了规律。在此之前,我们先设输入的数为\(n\)。\(n\)分三种情况。\(n\)是奇数;\(n\)是偶数;\(n\)小于等于......
  • 洛谷 P9503『MGOI』Simple Round I | B. 魔法照相馆 の 题解
    这道题是一道模拟题,坑点不多,但是细节特多,所以导致大部分人\(A\)不了这道题。这道题我也写了注释,如果思路没明白可以看代码和注释的。先创建一个长度为\(3\)的字符串\(s1\),这个字符串的意思就是模拟现在的这几个幕布的情况,这里分了四个字符代表着四种情况,详细如下该字符串......
  • 洛谷 P9502 『MGOI』Simple Round I | A. 魔法数字 の 题解
    直接用pow()函数暴力判断即可,一旦不符合条件就立即跳出循环,要注意开longlong或unsignedlonglong。#include<iostream>#include<cmath>usingnamespacestd;unsignedlonglongn,num;intmain(){cin>>n;for(unsignedlonglongi=2;i<=n;i+=......
  • 洛谷 UVA10852 Less Prime の 题解
    这道题更像是结论题,因为他要推一个小结论,才能做出这道题。大概思路是先打个素数表,存到数组\(a\)内,\(cnt\)是素数表的最后一个元素的下标。之后循环\(M\)次去输入\(N\),每次输入\(N\)之前都要定义两个变量,分别是\(mx\),存\(n-p\cdotx\)的最大值,\(ans\)则是当\(n-......