/*
名称:CCF 201403-2(窗口)
说明:今天闲着没事,做题CCF练练手。这题并不是很难,但过程中也遇到了一些问题主要是关于STL的使用的。虽然以前一直在用STL,但都是找到什么用什么(就像这题一开始用的是vector,虽然也能达到同样的目的,但效率不高),今天, 在此总结下:
对于STL我们一般常用的是vector、deque、list、stack、queue这些(还用set等,那些用的较少,至少我用的较少)。
对于vector,可以帮他当成一个数组,STL给我们最直接的函数就是从尾部进行插入删除(push_back,pop_back),虽然我们可以利用其他的函数接口和迭代器达到堆栈、队列等数据结构,但始终是多了一道手续(qeque可以直接实现)。所以,vector一般用于从尾部插入数据,然后极少进行插入、删除等操作(除非在尾部)。一般来说,数据确定之后,它主要用于查询。
对于deque(双向队列),以前没怎么用过,今天查了才了解,这个太好用了。基本上,它包括了vector、queue、stack的全部操作, 即用vector、stack、queue能实现的操作,用deque都能直接实现。它可以从尾部添(push_back)、尾部删除(pop_back)、头部添加(push_front)、头部删除(pop_front);
对于queue(单向队列)、stack(栈),它们知识简单地装饰deque容器而成为另外的一种容器。
对于list(双向链表),它是链表。上面的几个都是内存空间连续,list是分散的。STL也提供了list的头部、尾部操作,但是它终究还是链表类型。不能随机访问,但是对于经常需要增删的操作,用list还是蛮适合的。
*/
#include<iostram>
#include<list>
using namespace std;
class Rectangle
{
public:
int x1,y1; //左下角坐标
int x2,y2;
int num;
Rectangle(int x1 = 0,int y1 = 0,int x2 = 0,int y2 = 0,int pos = 0)
{
this->x1 = x1;
this->x2 = x2;
this->y1 = y1;
this->y2 = y2;
num = pos;
}
//判断是否在矩形内
bool IsInRec(int x,int y)
{
if((x>=x1 && x<=x2) && (y>=y1 && y<=y2))
return true;
else
return false;
}
};
class Window
{
public:
//vector<Rectangle> wins_0;
list<Rectangle> wins_1;
//初始化窗口
void InitWindows(int x1,int y1,int x2,int y2,int pos)
{
Rectangle *temp = new Rectangle(x1,y1,x2,y2,pos);
// wins_0.push_back(*temp);
wins_1.push_front(*temp);
}
//判断是哪个窗口
int WhichWin(int x,int y)
{
list<Rectangle>::iterator iter1;
for(iter1 = wins_1.begin();iter1 != wins_1.end();++iter1)
{
if(iter1->IsInRec(x,y))
{
int temp = iter1->num;
ChangeWin(iter1);
return temp;
}
}
return -1;
}
//改变窗口
void ChangeWin(list<Rectangle>::iterator iter)
{
Rectangle *temp = new Rectangle();
*temp = *iter;
wins_1.erase(iter);
wins_1.push_front(*temp);
}
};
int main()
{
Window ex;
int N,M;
cin>>N>>M;
int x1,y1,x2,y2,pos = 0;
for(int i = 0;i<N;++i)
{
cin>>x1>>y1>>x2>>y2;
ex.InitWindows(x1,y1,x2,y2,i+1);
}
for(int i = 0;i<M;++i)
{
cin>>x1>>y1;
pos = ex.WhichWin(x1,y1);
if(-1 == pos)
cout<<"IGNORED"<<endl;
else
cout<<pos<<endl;
}
return 0;
}