专栏文章

题解:UVA12207 That is Your Queue

UVA12207题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mipea72z
此快照首次捕获于
2025/12/03 10:35
3 个月前
此快照最后确认于
2025/12/03 10:35
3 个月前
查看原文

UVA12207 That is Your Queue

解题思路

容易发现,对于病人序号的访问是环状的,且中间有插入和删除操作,因此可以使用环状双向链表。
考虑到 1p1091\le p\le 10^9,建如此庞大的链表似乎不合适。然而,可以发现,当 cpc\le p 时,访问不会是环装的,因为操作次数不可能将所有病人序号全都访问一遍。
进行分类讨论。当 p<cp<c 时,使用环状双向链表,大小不会超过 30003000;当 cpc\le p 时,用 map 记录是否病人已经被访问,用栈记录被提前安置的病人。

完整代码

CPP
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<stack>
#include<map>
using namespace std;
struct Node{
	int id;
	Node *lst,*nxt;
}p[3006],*head;
int n,c,cases=0;
map<int,bool>m;
stack<int>st;
int main()
{
	while(~scanf("%d %d",&n,&c))
	{
		if(n+c==0)return 0;
		printf("Case %d:\n",++cases);
		if(c>n)
		{
			head=&p[0];
			for(int i=0;i<n;i++)
			{
				p[i].id=i+1;
				p[i].nxt=&p[(i+1)%n];
				p[i].lst=&p[(i+n-1)%n];
			}
			for(int i=1;i<=c;i++)
			{
				char opt;
				scanf("\n%c",&opt);
				if(opt=='N')
				{
					printf("%d\n",head->id);
					head=head->nxt;
				}
				else{
					int x;
					scanf("%d",&x);--x;
					if(head==&p[x])continue;
					p[x].lst->nxt=p[x].nxt;
					p[x].nxt->lst=p[x].lst;
					head->lst->nxt=&p[x];
					p[x].lst=head->lst;
					head->lst=&p[x];
					p[x].nxt=head;
					head=head->lst;
				}
			}
		}
		else{
			while(!st.empty())st.pop();
			m.clear();
			char opt;
			int h=1;
			for(int i=1;i<=c;i++)
			{
				scanf("\n%c",&opt);
				while(!st.empty()&&m[st.top()])st.pop();
				if(opt=='N'){
					if(st.empty())
					{
						while(m[h])h++;
						m[h]=1;
						printf("%d\n",h++);
					}
					else{
						if(!m[st.top()])printf("%d\n",st.top());
						m[st.top()]=1;
						st.pop();
					}
				}
				else{
					int x;
					scanf("%d",&x);
					st.push(x);
					m[x]=0;
				}
			}
		}
	}
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...