針對CSP這道題,作為第二道要比-2要難一些,不過也沒有難到哪里去,只要理解題意c語言實(shí)現(xiàn)鼠標(biāo)點(diǎn)擊,做起來還是很簡單很簡單的
不過題目下方還是貼心的添加了題目的解讀,如果不會(huì)可以思考一下,加油
窗口
前言
這篇文章大概介紹了csp測試模擬題的-2,大概瀏覽了一下題目,越是接近最新考題(2023年)題目就越復(fù)雜冗長,我還是喜歡題目簡潔一些的,所以,喜歡從最舊的考題開始做,建議大家也和我一樣,給自己一些信心,加油!
一、題目 問題描述
在某圖形操作系統(tǒng)中,有 N 個(gè)窗口,每個(gè)窗口都是一個(gè)兩邊與坐標(biāo)軸分別平行的矩形區(qū)域。窗口的邊界上的點(diǎn)也屬于該窗口。窗口之間有層次的區(qū)別,在多于一個(gè)窗口重疊的區(qū)域里,只會(huì)顯示位于頂層的窗口里的內(nèi)容。
當(dāng)你點(diǎn)擊屏幕上一個(gè)點(diǎn)的時(shí)候,你就選擇了處于被點(diǎn)擊位置的最頂層窗口,并且這個(gè)窗口就會(huì)被移到所有窗口的最頂層,而剩余的窗口的層次順序不變。如果你點(diǎn)擊的位置不屬于任何窗口,則系統(tǒng)會(huì)忽略你這次點(diǎn)擊。
現(xiàn)在我們希望你寫一個(gè)程序模擬點(diǎn)擊窗口的過程。
輸入格式
輸入的第一行有兩個(gè)正整數(shù),即 N 和 M。(1 ≤ N ≤ 10,1 ≤ M ≤ 10)
接下來 N 行按照從最下層到最頂層的順序給出 N 個(gè)窗口的位置。 每行包含四個(gè)非負(fù)整數(shù) x1, y1, x2, y2,表示該窗口的一對頂點(diǎn)坐標(biāo)分別為 (x1, y1) 和 (x2, y2)。保證 x1 < x2,y1 2。
接下來 M 行每行包含兩個(gè)非負(fù)整數(shù) x, y,表示一次鼠標(biāo)點(diǎn)擊的坐標(biāo)。
題目中涉及到的所有點(diǎn)和矩形的頂點(diǎn)的 x, y 坐標(biāo)分別不超過 2559 和1439。
輸出格式
輸出包括 M 行,每一行表示一次鼠標(biāo)點(diǎn)擊的結(jié)果。如果該次鼠標(biāo)點(diǎn)擊選擇了一個(gè)窗口,則輸出這個(gè)窗口的編號(hào)(窗口按照輸入中的順序從 1 編號(hào)到 N);如果沒有,則輸出""(不含雙引號(hào))。
樣例輸入
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
樣例說明
第一次點(diǎn)擊的位置同時(shí)屬于第 1 和第 2 個(gè)窗口,但是由于第 2 個(gè)窗口在上面,它被選擇并且被置于頂層。
第二次點(diǎn)擊的位置只屬于第 1 個(gè)窗口,因此該次點(diǎn)擊選擇了此窗口并將其置于頂層。現(xiàn)在的三個(gè)窗口的層次關(guān)系與初始狀態(tài)恰好相反了。
第三次點(diǎn)擊的位置同時(shí)屬于三個(gè)窗口的范圍,但是由于現(xiàn)在第 1 個(gè)窗口處于頂層,它被選擇。
最后點(diǎn)擊的 (0, 5) 不屬于任何窗口。
二、解題思路 1.了解題目含義
注意的是,這個(gè)是很貼近生活的一道題目,在日常生活中,我們最后打開的網(wǎng)頁在最上面,點(diǎn)擊位于下面的網(wǎng)頁時(shí),所點(diǎn)擊的網(wǎng)頁會(huì)置頂,我們用頁面的兩個(gè)對角頂點(diǎn)代表網(wǎng)頁范圍,點(diǎn)擊位置用坐標(biāo)表示
2.博主有話說
在最開始的時(shí)候,博主也沒怎么讀題,因?yàn)闃永狞c(diǎn)擊位置剛好是臨界點(diǎn)位置,所以博主就讓坐標(biāo)等于兩個(gè)臨界點(diǎn)其中的一個(gè)才會(huì)顯示點(diǎn)擊頁面的編號(hào)
第二個(gè)錯(cuò)誤是博主并沒有改變置頂頁面的位置,導(dǎo)致沒有點(diǎn)擊頁面就會(huì)將其置頂 的功能
第三個(gè)錯(cuò)誤是c語言實(shí)現(xiàn)鼠標(biāo)點(diǎn)擊,博主沒有想到頁面打開的順序應(yīng)該和位置順序相反,也就是說應(yīng)該是“后來者居上”
這是博主的三個(gè)錯(cuò)誤,希望大家可以避免
三、代碼
#include
#include
typedef struct list{
int data;
struct list *next;
}list,*plist;
typedef struct sqrt{
int first[2];
int second[2];
}sqrt,*psqrt;
int main(){
sqrt a[11];
plist p=(plist)malloc(sizeof(list));
plist head=p;
int m,n,i;
int x1,y1,x2,y2,x,y;
int j,k;
scanf("%d %d",&m,&n);
for(i=0;i<m;i++){
scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
a[i].first[0]=x1;
a[i].first[1]=y1;
a[i].second[0]=x2;
a[i].second[1]=y2;
plist bb=(plist)malloc(sizeof(list));
bb->data=m-i-1;
bb->next=NULL;
p->next=bb;
p=bb;
}
for(i=0;i<n;i++){
scanf("%d %d",&x,&y);
plist bb=head;
int flag=0;
while(bb->next){
j=bb->next->data;
if(x>=a[j].first[0]&&x<=a[j].second[0]&&y>=a[j].first[1]&&y<=a[j].second[1])
{
printf("%d\n",j+1);
flag=1;
plist r=bb->next;
bb->next=bb->next->next;
r->next=head->next;
head->next=r;
break;
}
bb=bb->next;
}
if(flag==0)
printf("IGNORED\n");
}
return 0;
}
解釋一下代碼
博主和眾多程序員一樣,喜歡別人的代碼有注釋,但自己最討厭寫注釋
所以,博主在這里解釋一下自己的代碼
先創(chuàng)建兩個(gè)結(jié)構(gòu)體,一個(gè)存頁面信息,一個(gè)存位置
然后進(jìn)入循環(huán)----輸入信息----點(diǎn)擊頁面后更新位置鏈表的信息
其實(shí)代碼可以更加簡介,但是為了好理解,多用了一些中間變量表示位置,所以顯得代碼有點(diǎn)冗長
給大家看一下運(yùn)行結(jié)果
注意記得寫
return 0;
否則運(yùn)行錯(cuò)誤