HDU 1387(模拟优化)
这个题目的意思很简单 但是如果照着模拟一定会TLE 所以在模拟上也需要很大的技巧
先前我使用了并查集来表示团的关系 但后来发先直接使用hash映射就好了 所以不必想这么复杂 而后就是对于队列的模拟
由于牵涉到的是插入和删除操作 所以应该使用链表结构 比如stl中的list容器 如果单纯使用该结构一定会超时 所以必须进行优化
使用桶结构 将每个队伍看做是一个桶 然后按先来后到的顺序进表 若成员在表中 则定位到该队伍的链表内将其插入 否则插入末尾 并创建队伍链
而且这也是我碰到第一个使用了指针优化的题目 用指针数组定位各个队伍的链表地址 以实现快速访问 感觉数据结构对于模拟题来说也是很有用的
以下附上代码
#include <iostream>
#include <list>
using namespace std;
const long MAXN=1000000;
long rank[MAXN];
char key[500];
list < list<long> > q;
list<long> *pos[1001];
int main()
{
long n;
long b=1;
while (scanf("%ld",&n)!=EOF&&n)
{
long i,j;
memset(rank,-1,sizeof(rank));
for (i=0;i<n;++i)
{
long m;
scanf("%ld",&m);
for (j=0;j<m;++j)
{
long from;
scanf("%ld",&from);
rank[from]=i;
}
}
for(i=0;i<1001;i++)
{
pos[i]=NULL;
}
q.clear();
printf("Scenario #%ld\n",b);
++b;
while(1)
{
scanf("%s",key);
if (strcmp(key,"DEQUEUE")==0)
{
long num=(q.front()).front();
printf("%ld\n",num);
(q.front()).pop_front();
if ((q.front()).empty())
{
q.pop_front();
pos[rank[num]]=NULL;
}
}
else if (strcmp(key,"ENQUEUE")==0)
{
long to;
list<long> t;
scanf("%ld",&to);
if (rank[to]==-1)//不成团
{
t.push_back(to);
q.push_back(t);
t.clear();
}
else
{
if (pos[rank[to]]==NULL)//队伍不在
{
t.push_back(to);
q.push_back(t);
t.clear();
pos[rank[to]]=&(q.back());
}
else
{
pos[rank[to]]->push_back(to);
}
}
}
else
{
printf("\n");
break;
}
}
}
return 0;
}
#include <list>
using namespace std;
const long MAXN=1000000;
long rank[MAXN];
char key[500];
list < list<long> > q;
list<long> *pos[1001];
int main()
{
long n;
long b=1;
while (scanf("%ld",&n)!=EOF&&n)
{
long i,j;
memset(rank,-1,sizeof(rank));
for (i=0;i<n;++i)
{
long m;
scanf("%ld",&m);
for (j=0;j<m;++j)
{
long from;
scanf("%ld",&from);
rank[from]=i;
}
}
for(i=0;i<1001;i++)
{
pos[i]=NULL;
}
q.clear();
printf("Scenario #%ld\n",b);
++b;
while(1)
{
scanf("%s",key);
if (strcmp(key,"DEQUEUE")==0)
{
long num=(q.front()).front();
printf("%ld\n",num);
(q.front()).pop_front();
if ((q.front()).empty())
{
q.pop_front();
pos[rank[num]]=NULL;
}
}
else if (strcmp(key,"ENQUEUE")==0)
{
long to;
list<long> t;
scanf("%ld",&to);
if (rank[to]==-1)//不成团
{
t.push_back(to);
q.push_back(t);
t.clear();
}
else
{
if (pos[rank[to]]==NULL)//队伍不在
{
t.push_back(to);
q.push_back(t);
t.clear();
pos[rank[to]]=&(q.back());
}
else
{
pos[rank[to]]->push_back(to);
}
}
}
else
{
printf("\n");
break;
}
}
}
return 0;
}