CSP201403-2:窗口
引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中國計算機學會(CCF)發起的"計算機職業資格認證"考試,針對計算機軟件開發、軟件測試、信息管理等領域的專業人士進行能力認證。認證對象是從事或將要從事IT領域專業技術與技術管理人員,以及高校招考研究生的復試對象。
- 問題描述
在某圖形操作系統中,有 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) 不屬於任何窗口。
- 源代碼
# include <stdio.h> # include <stdlib.h> # include <memory.h>
//存放窗口坐標 struct windows { int x1; int y1; int x2; int y2; int priority; //優先級 };
//存放操作 struct operation { int x; int y; int result; };
int main(void) { int n; //n個窗口 int m; //m次操作 scanf("%d", &n); scanf("%d", &m);
windows *pWin = (windows *)malloc(sizeof(struct windows) * n); memset(pWin, 0, sizeof(struct windows) * n); operation *pOprt = (operation *)malloc(sizeof(struct operation) * m); memset(pOprt, 0, sizeof(struct operation) * m);
//讀入窗口坐標 for (int i = 0; i < n; i++) { scanf("%d", &(pWin[i].x1)); scanf("%d", &(pWin[i].y1)); scanf("%d", &(pWin[i].x2)); scanf("%d", &(pWin[i].y2)); pWin[i].priority = i + 1; } //讀入模擬鼠標的操作 for (int i = 0; i < m; i++) { scanf("%d", &(pOprt[i].x)); scanf("%d", &(pOprt[i].y)); }
//找到滿足條件的窗口:操作的坐標在窗口內且窗口的優先級比當前的窗口的優先級高 for (int i = 0; i < m; i++) { int curPri = 0; for (int j = 0; j < n; j++) { if ((pOprt[i].x >= pWin[j].x1) && (pOprt[i].x <= pWin[j].x2)) { if ((pOprt[i].y >= pWin[j].y1) && (pOprt[i].y <= pWin[j].y2)) { if (pWin[j].priority > curPri) { curPri = pWin[j].priority; pOprt[i].result = j + 1; } } } }
if (curPri == 0) { pOprt[i].result = 0; } else //每次操作之後要調整窗口優先級 { for (int j = 0; j < n; j++) //選中的窗口優先級最高:n { if (pOprt[i].result == j+1) { pWin[j].priority = n; }
if (j+1 > pOprt[i].result) //優先級比選中窗口未選中前的優先級高的窗口,優先級-1 { pWin[j].priority -= 1; } } } }
for (int i = 0; i < m; i++) { if (pOprt[i].result == 0) { printf("IGNORED\n"); } else { printf("%d\n", pOprt[i].result); } }
free(pWin); free(pOprt);
return 0; } |
CSP201403-2:窗口