UVa OJ 142 – Mouse Clicks (滑鼠點擊)

來源:互聯網
上載者:User
Problem
問題

A typical windowing system on a computer will provide a number of icons on the screen as well as some defined regions. When the mouse button is clicked, the system has to determine where the cursor is and what is being selected. For this problem we assume that a mouse click in (or on the border of) a region selects that region, otherwise it selects the closest visible icon (or icons in the case of a tie).

一般的電腦視窗系統都會在螢幕上放置很多表徵圖和預定義的地區。當滑鼠鍵按下時,系統會檢測滑鼠點擊的位置並確定點中了什麼。在這個問題中,我們認為滑鼠點擊一個地區(點在邊上也算)就選中該地區,否則就選中離的最近的可見表徵圖(可能會有多個)。

Consider the following screen:
觀察下面的螢幕:

 

 

A mouse click at 'a' will select region A. A mouse click at 'b' will select icon 1. A mouse click at 'c' will select icons 6 and 7. A mouse click at 'd' is ambiguous. The ambiguity is resolved by assuming that one region is in front of another. In the data files, later regions can be assumed to be in front of earlier regions. Since regions are labelled in order of appearance (see later) 'd' will select C. Note that regions always overlap icons so that obscured icons need not be considered and that the origin (0,0) is at the top left corner.
滑鼠點在“a”處將選中地區A,點在“b”處將選中表徵圖1,點在“c”處將選中表徵圖6和7,而點在'd'處則會產生一個歧意。當產生歧意時應選中較為靠前的一個地區。在輸入的資料中,後給出的地區應被視為在先給出的地區之前。注意,地區將會覆蓋相應位置的所有表徵圖,被覆蓋的圖應被忽略。座標原點(0, 0)位於左下角。

Write a program that will read in a series of region and icon definitions followed by a series of mouse clicks and return the selected items. Coordinates will be given as pairs of integers in the range 0..499 and you can assume that all icons and regions lie wholly within the screen. Your program must number all icons (even invisible ones) in the order of arrival starting from 1 and label regions alphabetically in the order of arrival starting from 'A'.
寫一個程式讀入一組地區和表徵圖的定義,以及一組滑鼠點擊的位置,並返回選中的對象。每個座標都是兩個0到499的整數,你可以認為所有的表徵圖和地區都沒有在螢幕外面的部分。你的程式應該按輸入的順序從1開始對表徵圖進行編號,並按照輸入的順序從“A”開始以字母表對地區進行編號。

 

Input
輸入

Input will consist of a series of lines. Each line will identify the type of data: I for icon, R for region and M for mouse click. There will be no separation between the specification part and the event part, however no icon or region specifications will follow the first mouse click. An I will be followed by the coordinates of the centre of the icon, R will be followed by the coordinates of the top left and bottom right corners respectively and M will be followed by the coordinates of the cursor at the time of the click. There will always be at least one visible icon and never more than 25 regions and 50 icons. The entire file will be terminated by a line consisting of a single #.
輸入由多行組成。每行的開頭標註了資料的類型:I為表徵圖,R為地區,M為滑鼠點擊位置。資料定義部分的輸入和點擊事件部分的輸入之間沒有間隔,但開始輸入滑鼠資料後,將不再會出現表徵圖或地區資料。標誌I的後面是表徵圖中心的座標地,標誌R後面是左上方和右下角的座標,標誌M後面是滑鼠點擊時指標位置的座標。至少會有一個可見的表徵圖,最多有25個地區和50個表徵圖。全部輸入的資料由獨佔一行的單個字元#號表示結束。

 

Output
輸出

Output will consist of one line for each mouse click, containing the selection(s) for that click. Regions will be identified by their single character identifier, icon numbers will be written out right justified in a field of width 3, and where there is more than one icon number they will appear in increasing numerical order.
對應於每一個滑鼠點擊的事件,輸出一行選中的對象。地區由單個字母表示,表徵圖的應按靠右對齊,寬度為3的格式輸出,對於多於一個表徵圖被選中的情況應按照編號遞增的順序輸出。

 

Sample input
輸入樣本

I       216     28
R       22      19      170     102
I       40      150
I       96      138
I       36      193
R       305     13      425     103
I       191     184
I       387     200
R       266     63      370     140
I       419     134
I       170     102
M       50      50
M       236     30
M       403     167
M       330     83
#

 

Sample output
輸出樣本

A
  1
  6  7
C

 

Analysis
分析

這道題沒有什麼複雜的演算法,判斷點在矩形內和計算距離都是最基本的運算,直接按題目做就可以了。注意兩點:輸入的矩形和表徵圖不能隨意改變順序或刪除,否則在輸出時無法得到正確的編號;不要忘記忽略掉被矩形覆蓋掉的表徵圖。

 

Solution
解答
#include <iomanip>#include <iostream>#include <iterator>#include <deque>using namespace std;struct POINT {int x; int y;};struct RECT {POINT tl; POINT br;};//判斷點是否在矩形內bool PointInRect(const POINT &pt, const RECT &rc) {return (pt.x >= rc.tl.x && pt.x <= rc.br.x &&pt.y >= rc.tl.y && pt.y <= rc.br.y);}//計算兩點計距離的平方int PointDistance(const POINT &pt1, const POINT &pt2) {POINT Vec = {pt2.x - pt1.x, pt2.y - pt1.y};return (Vec.x * Vec.x + Vec.y * Vec.y);}//主函數int main(void) {deque<POINT> Icons, Clicks;deque<RECT> Rects;//迴圈讀入每一組資料for (char Tag = 0; cin >> Tag && Tag != '#'; ) {RECT rc;switch (Tag) {case 'I': //輸入表徵圖資料cin >> rc.tl.x >> rc.tl.y;Icons.push_back(rc.tl);break;case 'R': //輸入矩形資料cin >> rc.tl.x >> rc.tl.y >> rc.br.x >> rc.br.y;if (rc.br.x < rc.tl.x) *(int*)0 = 0;if (rc.br.y < rc.tl.y) *(int*)0 = 0;Rects.push_back(rc);if (Rects.size() > 26) *(int*)0 = 0;break;case 'M': //輸入滑鼠點擊事件(座標)cin >> rc.tl.x >> rc.tl.y;Clicks.push_back(rc.tl);break;}}deque<POINT>::iterator iIcon, iClick;deque<RECT>::iterator iRect;//檢查是否存在表徵圖被矩形覆蓋for (iIcon = Icons.begin(); iIcon != Icons.end(); ++iIcon) {for (iRect = Rects.begin(); iRect != Rects.end(); ++iRect) {if (PointInRect(*iIcon, *iRect)) {iIcon->x = 10000; //將該表徵圖移至無窮遠處,即將其忽略iIcon->y = 10000; //不能刪除,以免影響後面表徵圖的編號}}}//處理每一次滑鼠點擊事件for (iClick = Clicks.begin(); iClick != Clicks.end(); ++iClick) {//按題目要求,從後向前檢查是否點在某個矩形內deque<RECT>::reverse_iterator riRect;for (riRect = Rects.rbegin(); riRect != Rects.rend() &&!PointInRect(*iClick, *riRect); ++riRect);//如果找到點在某個矩型,輸出該矩形if (riRect != Rects.rend()) {cout << (char)(distance(riRect, Rects.rend()) - 1 + 'A') << endl;continue;}//尋找離滑鼠位置距離最近的表徵圖,存到動態數組SelIcons中deque<int> SelIcons(1, 1);deque<POINT>::iterator iNear = Icons.begin(), iIcon;int nNear = PointDistance(*iClick, *iNear);for (iIcon = iNear + 1; iIcon != Icons.end(); ++iIcon) {int nDist = PointDistance(*iClick, *iIcon); //計算距離if (nDist < nNear) {iNear = iIcon;nNear = nDist;SelIcons.clear(); //清空原先的數組,以新表徵圖代替SelIcons.push_back(distance(Icons.begin(), iIcon) + 1);}else if (nDist == nNear) { //發現同為最短距離的表徵圖則加入數組SelIcons.push_back(distance(Icons.begin(), iIcon) + 1);}}//按要求的格式輸出表徵圖的編號deque<int>::iterator iSel;for (iSel = SelIcons.begin(); iSel != SelIcons.end(); ++iSel) {cout << setw(3) << *iSel;}cout << endl;}return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.