【CCF】窗口

本文介绍了一种模拟图形操作系统中窗口点击及层级变化的算法。通过定义窗口类和链表类,实现点击屏幕时选中最顶层窗口的功能,并保持窗口层级顺序。输入窗口坐标和点击位置,输出每次点击所选窗口编号或提示。
题目2窗口
时间限制:1秒
空间限制:256MB
问题描述
在某图形操作系统中,有N个窗口,每个窗口都是一个两边与坐标轴分别平行的矩形区域。窗口的边界上的点也属于该窗口。窗口之间有层次的区别,在多于一个窗口重叠的区域里,只会显示位于顶层的窗口里的内容。
当你点击屏幕上一个点的时候,你就选择了处于被点击位置的最顶层窗口,并且这个窗口就会被移到所有窗口的最顶层,而剩余的窗口的层次顺序不变。如果你点击的位置不属于任何窗口,则系统会忽略你这次点击。现在我们希望你写一个程序模拟点击窗口的过程。
输入格式
输入的第一行有两个正整数,即N和M。(1≤N≤10,1≤M≤10)接下来N行按照从最下层到最顶层的顺序给出N个窗口的位置。每行包含四个非负整数x1,y1,x2,y2,表示该窗口的一对顶点坐标分别为(x1,y1)和(x2,y2)。保证x1<x2,y1<y2。
接下来M行每行包含两个非负整数x,y,表示一次鼠标点击的坐标。题目中涉及到的所有点和矩形的顶点的x,y坐标分别不超过2559和1439。
输出格式
输出包括M行,每一行表示一次鼠标点击的结果。如果该次鼠标点击选择了一个窗口,则输出这个窗口的编号(窗口按照输入中的顺序从1编号到N);如果没有,则输出"IGNORED"(不含双引号)。
输入样例
3 4
0 0 4 4
1 1 5 5
2 2 6 6
1 1
0 0
4 4
0 5 
输出样例
2
1
1
IGNORED
对样例的解释
第一次点击的位置同时属于第1和第2个窗口,但是由于第2个窗口在上面,它被选择并且被置于顶层。
第二次点击的位置只属于第1个窗口,因此该次点击选择了此窗口并将其置于顶层。现在的三个窗口的层次关系与初始状态恰好相反了。
第三次点击的位置同时属于三个窗口的范围,但是由于现在第1个窗口处于顶层,它被选择。
最后点击的(0,5)不属于任何窗口。

3


#include<iostream>
using namespace std;

class Window{
public:
	int x1,x2,y1,y2,n;
	Window(int x1,int y1,int x2,int y2){
		this->x1 = x1;
		this->x2 = x2;
		this->y1 = y1;
		this->y2 = y2;
	}
	Window(){}
	void setter(int x1,int y1,int x2,int y2){
		this->x1 = x1;
		this->x2 = x2;
		this->y1 = y1;
		this->y2 = y2;
	}
	bool isClicked(int x,int y){
		return x>=x1 && x<=x2 && y>=y1 && y<=y2;
	}
};

class Node{
	public:
		Window w;
		Node* next;
		Node(){
			next = NULL;
		}
};

class LinkedList{
private:

	Node* head;
	Node* last;
	int len ;
public:
	LinkedList(){
		head = NULL;
		last = NULL;
		len = 1;
	}
	~LinkedList(){
		Node*p=head;
		Node*q;
		while(p){
			q = p;
			p=p->next;
			delete q;
		}
	}
	void add(Window element){
		if(head){
			element.n = len ++;
			Node *p = new Node();
			p->next = head;
			head = p;
			p->w=element;
			
		}
		else{
			element.n = len ++;
			head = new Node();
			head->w = element;
			last = head;
			
		}
	}
	void remove(int i){
		Node* p=head;
		Node* q=NULL;
		if(i==0){
			q=p;
			head=head->next;
			delete q;
			return;
		}
		while(i--){
			q=p;
			p=p->next;
		}
		if(p->next){
			Node* m = p;
			p=p->next;
			q->next = p;
			delete m;
		}
		else{
			last = q;
			last->next=NULL;
			delete p;
		}
	}
	void changeFirst(int i){
		if(i==1 || i>len)return;
		Node *p=head;
		Node *q;
		i--;
		while(i--){
			q = p;
			p = p->next;
		}
		q->next=p->next;
		p->next = head;
		head = p;
	}
	void display(){
		Node* p = head;
		while(p){
			cout<<p->w.x1<<" "<<p->w.x2<<" "<<p->w.n<<endl;
			p=p->next;
		}
		cout<<endl;
	}
	bool check(int x,int y){
		int i = 1;
		Node* p = head;
		while(p){
			if(p->w.isClicked(x,y)){
				changeFirst(i);
				cout<<p->w.n<<endl;
				return true;
			}
			p=p->next;
			i++;
		}
		return false;
	}
	Node* gethead(){
		return head;
	}
};

int main(){
	int m,n,x,y,_x,_y;
	cin>>n>>m;
	LinkedList ll;
	Window w;
	while(n--){
		cin>>x>>y>>_x>>_y;
		w.setter(x,y,_x,_y);
		ll.add(w);
	}
	
	while(m--){
		cin>>x>>y;
		if(ll.check(x,y)){
		}
		else{
			cout<<"IGNORED"<<endl;
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值