CCF-CSP 窗口 JAVA

问题描述

试题编号:201403-2
试题名称:窗口
时间限制:1.0s
内存限制:256.0MB
问题描述:

问题描述

  在某图形操作系统中,有 N 个窗口,每个窗口都是一个两边与坐标轴分别平行的矩形区域。窗口的边界上的点也属于该窗口。窗口之间有层次的区别,在多于一个窗口重叠的区域里,只会显示位于顶层的窗口里的内容。
  当你点击屏幕上一个点的时候,你就选择了处于被点击位置的最顶层窗口,并且这个窗口就会被移到所有窗口的最顶层,而剩余的窗口的层次顺序不变。如果你点击的位置不属于任何窗口,则系统会忽略你这次点击。
  现在我们希望你写一个程序模拟点击窗口的过程。

输入格式

  输入的第一行有两个正整数,即 N 和 M。(1 ≤ N ≤ 10,1 ≤ M ≤ 10)
  接下来 N 行按照从最下层到最顶层的顺序给出 N 个窗口的位置。 每行包含四个非负整数 x1, y1, x2, y2,表示该窗口的一对顶点坐标分别为 (x1, y1) 和 (x2, y2)。保证 x1 < x2,y1 2。
  接下来 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) 不属于任何窗口。

答题栏

试题分析:使用链表实现,链表中保存窗户的编号、一对坐标,和下一个窗口的位置。链表从头到尾,存放从顶层到底层窗口位置,每次鼠标点击,从链表头部开始检索,鼠标点击的窗口位置,首次检索到的窗口即为鼠标点击的最上边的窗口,返回窗口编号,将鼠标点击的窗口移到链表头部。

import java.util.Scanner;

//链表结构
class Pos{
	private int id;
	private int x1;
	private int y1;
	private int x2;
	private int y2;
	private Pos next;

	public int getX1() {
		return x1;
	}
	public void setX1(int x1) {
		this.x1 = x1;
	}
	public int getY1() {
		return y1;
	}
	public void setY1(int y1) {
		this.y1 = y1;
		
	}
	public int getX2() {
		return x2;
	}
	public void setX2(int x2) {
		this.x2 = x2;
	}
	public int getY2() {
		return y2;
	}
	public void setY2(int y2) {
		this.y2 = y2;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public Pos getNext() {
		return next;
	}
	public void setNext(Pos next) {
		this.next = next;
	}
}

public class Main {
	
	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
		int N ,M ;
		N = s.nextInt();
		M = s.nextInt();
		//ArrayList<pos> pp = new ArrayList<pos>();
		Pos[] p =new Pos[N]; 
		//int[][] a =new int[N][5];
		Pos head=new Pos();
        
        ///录入窗口信息
		int i;
		for(i=0; i<N; i++) {
			p[i] = new Pos();
			p[i].setId(i+1);		  //窗口编号
			p[i].setX1(s.nextInt());//x1
			p[i].setY1(s.nextInt());//y1
			p[i].setX2(s.nextInt());//x2
			p[i].setY2(s.nextInt());//y2
			if(i==0)
				p[i].setNext(null);
			else
				p[i].setNext(p[i-1]);
		}
		head.setNext(p[i-1]);//最上边的窗口
		
		int x, y;            //(x,y)鼠标点击的位置
		for(i=0; i<M; i++) {
			x = s.nextInt();
			y = s.nextInt();
			Pos index=null;
			
            //检索鼠标点击的窗口
			for(index=head.getNext(); index!=null; index= index.getNext()) {
				if(x >= index.getX1() && x <= index.getX2() && y >= index.getY1() && y <= index.getY2() ) {
					System.out.println(index.getId());    //输出窗口编号
					break;
				}
			}
			
            ///表示鼠标点击到所有窗口之外的位置
			if(index==null) {
				System.out.println("IGNORED");
				continue;
			}
			
			//将点击的窗口移动到链表头部
            ///1、如果点击的是顶层的窗口,链表不需要移动
			if(head.getNext()==index) {
				continue;
			}	
			///2、鼠标点击非顶层的窗口,将点击的窗口移到顶层
			Pos index2 = null;
			for(index2=head.getNext(); index2.getNext()!=index; index2=index2.getNext()) {
			}
			index2.setNext(index.getNext());
			index.setNext(head.getNext());
			head.setNext(index);

		}

	}
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值