当前位置: 代码迷 >> 综合 >> 201403-2
  详细解决方案

201403-2

热度:91   发布时间:2023-09-22 23:46:56.0
问题描述

试题编号: 201403-2
试题名称: 窗口
时间限制: 1.0s
内存限制: 256.0MB
问题描述:
问题描述
在某图形操作系统中,有 N 个窗口,每个窗口都是一个两边与坐标轴分别平行的矩形区域。窗口的边界上的点也属于该窗口。窗口之间有层次的区别,在多于一个窗口重叠的区域里,只会显示位于顶层的窗口里的内容。
  当你点击屏幕上一个点的时候,你就选择了处于被点击位置的最顶层窗口,并且这个窗口就会被移到所有窗口的最顶层,而剩余的窗口的层次顺序不变。如果你点击的位置不属于任何窗口,则系统会忽略你这次点击。
  现在我们希望你写一个程序模拟点击窗口的过程。
输入格式
输入的第一行有两个正整数,即 N 和 M。(1 ≤ N ≤ 10,1 ≤ M ≤ 10)
  接下来 N 行按照从最下层到最顶层的顺序给出 N 个窗口的位置。 每行包含四个非负整数 x 1, y 1, x 2, y 2,表示该窗口的一对顶点坐标分别为 (x 1, y 1) 和 (x 2, y 2)。保证 x 1 < x 2,y 1 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) 不属于任何窗口。
问题分析:

问题的关键是创建窗口的结构体后怎么表示窗口的顺序。这里是用一个数组来表示窗口的顺序,对应的数组的值为窗口的编号。数组的下标越小,对应的编号窗口越靠前。

代码:

  1. #include <iostream>
  2. using namespace std;
  3. /* run this program using the console pauser or add your own getch, system("pause") or input loop */
  4. int n,m;  //n个窗口 m个点击事件 
  5. struct window
  6. {
  7. int winfo; //窗口的编号 
  8. int x1,y1,x2,y2;
  9. };
  10. struct click
  11. {
  12. int x,y;
  13. };
  14. window w[12];
  15. click c[11];


  16. int order[11]; //纪录窗口顺序的数组
  17.  
  18. string ans[11];
  19. int length=0; 


  20. int main(int argc, char *argv[]) {
  21. while(cin>>n>>m)
  22. {
  23. //输入n个窗口   
  24. for(int i=1;i<=n;i++)
  25. {
  26. int tx1,ty1,tx2,ty2;
  27. cin>>tx1>>ty1>>tx2>>ty2;

  28. w[i].x1=tx1;
  29. w[i].y1=ty1;
  30. w[i].x2=tx2;
  31. w[i].y2=ty2;
  32. w[i].winfo =i;

  33. }
  34. //初始化窗口顺序的数组order
  35. for(int i=0;i<n;i++)
  36. {
  37. order[i]=n-i;  //order[i]的值为对应窗口的编号 i越小对应窗口的越靠前 
  38. //i == 0 窗口编号 2  既2号窗口在最前 
  39. //输入m个鼠标点击次数
  40. for(int i=0;i<m;i++)
  41. {
  42. int tx,ty;
  43. cin>>tx>>ty;
  44. c[i].x=tx;
  45. c[i].y=ty;
  46. }
  47. //判断m次点击事件

  48. for(int i=0;i<m;i++)
  49. {
  50. int winio=-1;
  51. //从窗口最上层开始判断 
  52. int j;
  53. for(j=0;j<n;j++)
  54. {
  55.  int temp_w=order[j];  //获得当前最靠上的窗口的编号 
  56.  if((c[i].x <= w[temp_w].x2 && c[i].x >= w[temp_w].x1) &&
  57.   (c[i].y <= w[temp_w].y2 && c[i].y >= w[temp_w].y1))
  58.  {
  59. //i次点击到了这个窗口 
  60. //1.纪录其窗口号 
  61. winio=temp_w;
  62. //cout<<temp_w<<endl;
  63. //2.将此窗口移动到最前 
  64. for(int p=j;p>0;p--) //要从后开始移动 保证前面的数据不被覆盖 
  65. {
  66. order[p]=order[p-1];
  67. }
  68. order[0]=temp_w;
  69. break;  
  70. }
  71. else
  72. {
  73. //i次点击没有点到此窗口 判断下一个窗口 
  74. }
  75. if(winio == -1)
  76. {
  77. cout<<"IGNORED"<<endl;
  78. }
  79. else
  80. {
  81. cout<<winio<<endl;
  82. }
  83. }
  84. }
  85. return 0;
  86. }
注意:在移动数组时,需要从被替代的位置开始移动,防止有效信息被覆盖。