题目大意:
有个所谓的team排序, 给出t个队伍,以及这些队伍的成员。 然后进行排队。
ENQUEUE x: 把x插入队列中时。如果队列没有该元素的队员,则插入队列的最后面。如果队列中已经有了他的队员,那么插入最后一个队员之后。
DEQUEUE: 把队头的元素删除,并且输出
STOP: 停止
解题思路:
如果对链表熟悉,要模拟这个过程并不难。 STL 中的list挺好用的, 是双向循环链表。 end()成员函数返回链接首位的那个迭代其。 题目的一个关键过程是进行查询元素x时属于哪个队伍(可以用二分查找加速, 提高的速度很客观),还可以开一个超大的数组,用坐标映射元素值,数组保存队伍号,这样的话查找元素的队伍只需要O(1)的时间,是最快的。 然后更关键的一步是,每次插入位置的查找,如果每次的插入都要进行查找一次位置,肯定会TLE。可以另外开一个迭代器数组保存某队伍在队列中的最后一个位置的迭代器。
以上思路是TLE以后参考大牛的,我自己用纯C手写了一遍,STL固然好用,不过纯C手写收获也很多,查找元素我没有用二分,而是开了个elem数组进行映射,时间复杂度O(1), 查找也是类似开一个迭代器数组,只不过C语言没有C++的迭代器,就是一个指针数组而已。
下面是我的代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int len[2000], num, n, a, first;
int q[2000][2000], print[200002];
typedef struct team_queue
{
int num;
struct team_queue * next;
}node;
node * front;
node * rear;
node * last[2000];
int elem[1000000];
node * is_team( int num )
{
return last[elem[num]];
};
void output()
{
for( int i = 0; i < a; i++ )
printf( "%d\n", print[i] );
printf( "\n" );
};
void enqueue( int num )
{
node * p;
node * q;
if( first )
{
p = (node*)malloc(sizeof(node));
p->num = num;
p->next = NULL;
front = rear = p;
first = 0;
last[elem[num]] = front;
return ;
}
if( p = is_team(num) )
{
if( p == rear )
{
p = (node*)malloc(sizeof(node));
p->num = num;
p->next = NULL;
rear->next = p;
rear = rear->next;
last[elem[num]] = rear;
}
else
{
node * temp = (node*)malloc(sizeof(node));
temp->num = num;
q = p->next;
p->next = temp;
temp->next = q;
last[elem[num]] = temp;
}
}
else
{
p = (node*)malloc(sizeof(node));
p->num = num;
p->next = NULL;
rear->next = p;
rear = rear->next;
last[elem[num]] = rear;
}
};
void dequeue()
{
print[a++] = front->num;
if( last[elem[front->num]] == front )
last[elem[front->num]] = NULL;
front = front->next;
};
int main()
{
int time, i, j;
char input[20];
time = 1;
while( scanf( "%d", &n ) )
{
if( n == 0 )
break;
for( i = 0; i < n; i++ )
{
scanf( "%d", &len[i] );
for( j = 0; j < len[i]; j++ )
{
scanf( "%d", &q[i][j] );
elem[q[i][j]] = i;
}
scanf( "\n" );
}
front = rear = NULL;
a = 0;
first = 1;
for( i = 0; i < n; i++ )
last[i] = NULL;
while( scanf( "%s\n", input ) )
{
if( !strcmp( "STOP", input) )
{
printf( "Scenario #%d\n", time++ );
output();
break;
}
if( !strcmp( "ENQUEUE", input) )
{
scanf( "%d", &num );
enqueue( num );
}
if( !strcmp( "DEQUEUE", input) )
dequeue();
}
}
return 0;
}