UVa 540 小团体队列

题意:队列中有小团体(队列)。当入队时,如果有该团体的元素在队列中,则新元素排到该团体的尾部,否则排到队列的尾部。出队时和正常的一样,队首元素出列。

思路:这个用STL很好模拟,用纯C的话,很直接会想到用二维数组来做,每个团体是其中的一个一维数组,最多再开一个数组来对小团体编号进行排队。但是当时没有看到题目中说的每个团体最后有1000个元素,这样的话我以为要开1000X200000的数组,忒大了~

然后用的链表来实现。这里仍然是避免了指针和动态分配内存等易出错的东西,(不过这个方法还是把自己弄晕了点~)用大数组来模拟。首先申请的MAXN个Node的数组anode即是这里最后会用到的Node数,cnt来计数。然后team数组是保存元素i的团体编号team[i],iindex数组是保存每个团体i在队列中最后一个元素的anode下标。然后front和rear指向这个逻辑上的队列的队首和队尾元素。每次入队出队时维护上述信息即可。调了几次才调通,总是会忽略一些情况,注释里有。

注意:index是string.h中的一个函数,在本地可通过,交到OJ上就CE了。所以改成了iindex。

开始以为输入数据是给了类别编号,看第一个示例,有两个3号类,就不能理解了。问了才发现那个3是该类个数,不是类别编号。所以,要看清题目,及题目要求,特别是对样例困惑的时候。

遇到WA时,可以构造大一点的数据来测试。(比如开始把cnt当rear指针用,很多示例都过得了,多测几种数据才发现错误)

Code:

#include<stdio.h>
#include<string.h>
#define MAXN  200010

struct Node
{
 int data;
 int next;
};

Node anode[MAXN];
int team[1000010];//相当于hash表,元素i在team[i]团体里
int cnt=0;//anode数组使用最大的计数,anode[0]不用,作为空元素
int iindex[1010];//每个小团体在队列中尾元素的anode数组编号
//int que[MAXN];//题中描述的队列,入队的是在anode数组编号
int front=1,rear=0;//终指向团体队列的队首,队尾。注意这里rear不能用cnt代替,两者不同 

int main()
{
 //freopen("540.in","r",stdin);
 //freopen("540.out","w",stdout);
 int t;
 int n=1;
 while((scanf("%d",&t)==1)&&t)
 {
  printf("Scenario #%d\n",n++);
  memset(iindex,0,sizeof(iindex));
  memset(team,0,sizeof(team));
  cnt=0;front=1;
  for(int i=0;i<t;++i)
  {
   int num=0,a=0;
   scanf("%d",&num);
   for(int j=0;j<num;++j)
   {
    scanf("%d",&a);
    team[a]=i;
   }
  }
  //input command
  char cmd[25];
  while(scanf("%s",cmd)==1)
  {
   if(cmd[0]=='E')
   {
    int b=0;
    scanf("%d",&b);
    anode[++cnt].data=b;
    if(iindex[team[b]]==0)//是该团体第一个元素
    {
     anode[cnt].next=0;
     iindex[team[b]]=cnt;
     anode[rear].next=cnt;//将新团体的第一个元素附在队尾
     rear=cnt;
    }
    else
    {
     if(iindex[team[b]]==rear) rear=cnt;
     //在该团体尾元素后插入新结点,并维护iindex
     int x=anode[iindex[team[b]]].next;
     anode[iindex[team[b]]].next=cnt;
     anode[cnt].next=x;
     iindex[team[b]]=cnt;
    }
   }//ifcmd
   else if(cmd[0]=='D')
   {
    printf("%d\n",anode[front].data);
    //判断该元素是否是该团体的尾元素,维护iindex
    int type=team[anode[front].data];
    if(iindex[type]==front) iindex[type]=0;

    front=anode[front].next;
    if(front==0) front=cnt+1;//当队列为空时,front应为下一个新结点的anode中编号
   }
   else
    break;
  }//while
  printf("\n");
 }
 return 0;
}
时间: 2024-08-04 22:14:27

UVa 540 小团体队列的相关文章

UVa 540 (团体队列) Team Queue

题意: 每个人都属于一个团体,在排队的时候,如果他所在的团体有人在队伍中,则他会站到这个团体的最后.否则站到整个队伍的队尾. 输出每次出队的人的编号. 分析: 容易看出,长队中,在同一个团体的人是排在一起的. 所以用两个队列模拟即可,一个队列保留团体的编号,另外一个队列数组存放的是团体中每个人的编号. 1 #include <cstdio> 2 #include <queue> 3 #include <map> 4 using namespace std; 5 6 co

UVA 540(队列)

Description  Team Queue  Queues and Priority Queues are data structures which are known to most computer scientists. The Team Queue, however, is not so well known, though it occurs often in everyday life. At lunch time the queue in front of the Mensa

对于公司中的小团体该怎么处理?

在很多公司中,都会存在一些小的团体,他们或以相同的兴趣或者住在一起而聚集再一起,对于不同阶段的公司,这些小团体,对于公司都是有一些影响.很多公司比较支持员工以兴趣为方向组成兴趣小组,然后开展相关的一些活动.增进员工之间的了解.但是更多的公司是比较忌惮公司内部的一些小团体,特别是涉及利益而促成的一些小团体.那么从公司的角度来看,对于这些小团体有什么影响. 首页积极的一面.公司内存存在的一些小的以兴趣为方向而形成的一些小团体.增加了公司的凝聚性,增进了公司员工之间的了解,对于工作的开展提供了较多的方

例题5-6 团体队列 Team Queue UVA - 540

还好吧,刚开始没想明白用什么数据结构来做,后来才想到用一个队列和一个队列数组,一个存当前队伍的排队队列,另一个存每个在排队的队伍内部的人员队列.其他的set什么的,都不是最重要的内容了. 卡了我三个点: 1.忘了控制空队出队,空队排头了,导致了RE一次.在写了判定条件之后RE没了,成了WA-_- 2.这次WA是因为没有及时清除中间变量.是比较隐含的中间变量,表示某个队伍是否已在总队伍中的set,我在某只队伍最后一个成员从总队伍中出队后,没有清楚set中这支队伍的标记.也就是说,这支队伍其实不存在

UVa 540 Team Queue(团队队列)

题意  模拟团队队列的入队和出队 STL应用  用一个队列维护团队编号  再用一个队列数组维护个体 #include <cstdio> #include <cstring> #include <queue> #include <map> using namespace std; const int N = 1000005; int team[N]; int main() { int cas = 0, n, t, a; char cmd[20]; while(

UVA - 540 Team Queue(STL,队列 )

Team Queue Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description Queues and Priority Queues are data structures which are known to most computer scientists. The Team Queue, however, is not so well known,

uva540-小团体队列

小白书里数据结构基础线性表的训练参考 题目链接 http://acm.hust.edu.cn/vjudge/problem/19518 解题思路 用到队列.大队列表示团体顺序,小队列表示团体内部顺序. 题目提示入队出队要常数时间... 于是用到两个映射 成员映射到团体序号.只需开个数组存每个成员的团体编号. 团体映射大队列里的编号.又要开个数组.最多有1000个团体,还好... 读入数据的时候记得忽略空格. 代码 #include<iostream> #include<fstream&g

UVa 540 queue的使用

背景:书上的思路很好,开始自己想的思路行不通,因为queue定义的操作太少,不可直接访问内部内容,也不可以插入. 思路:用了一个主队列,和一个队列数组.主队列里储存的是队名,每一个队名对应一个队列数组中的团体. 学习:1.用一个map来记录队员和队员的队名是十分好的方法,应为map内部是红黑树实现,查找效率是log(n). 代码: #include<iostream> #include<map> #include<string> #include<queue>

算法入门经典-第五章 例题5-6 团体队列

题目背景 队列和优先级队列是大多数计算机科学家都知道的数据结构.但是团队队列却不被人熟知,尽管在生活中经常出现.比如,午餐时间的食堂门口的队列就是一个团队队列.在一个团队队列中,每个元素属于一个团队.如果一个元素进入一个队列,它首先从头到尾地搜寻这个队列--检查是否它的队友(在同一个团队称之为队友)也在这个队列里.如果有,它就排在它队友的后面(:-D就是插队咯~~).如果没有,它就排在整个队列的最后,成为新的最后一名(/(ㄒoㄒ)/~真是不幸).在普通队列中出队是这样的:元素从头到尾的被处理,按