蓝桥杯第七届决赛JAVA真题----广场舞
LQ市的市民廣場(chǎng)是一個(gè)多邊形,廣場(chǎng)上鋪滿了大理石的地板磚。
地板磚鋪得方方正正,就像坐標(biāo)軸紙一樣。
以某四塊磚相接的點(diǎn)為原點(diǎn),地板磚的兩條邊為兩個(gè)正方向,一塊磚的邊長為橫縱坐標(biāo)的單位長度,則所有橫縱坐標(biāo)都為整數(shù)的點(diǎn)都是四塊磚的交點(diǎn)(如果在廣場(chǎng)內(nèi))。
廣場(chǎng)的磚單調(diào)無趣,卻給跳廣場(chǎng)舞的市民們提供了絕佳的參照物。每天傍晚,都會(huì)有大批市民前來跳舞。
舞者每次都會(huì)選一塊完整的磚來跳舞,兩個(gè)人不會(huì)選擇同一塊磚,如果一塊磚在廣場(chǎng)邊上導(dǎo)致缺角或者邊不完整,則沒人會(huì)選這塊磚。
(廣場(chǎng)形狀的例子參考【圖1.png】)
現(xiàn)在,告訴你廣場(chǎng)的形狀,請(qǐng)幫LQ市的市長計(jì)算一下,同一時(shí)刻最多有多少市民可以在廣場(chǎng)跳舞。
【輸入格式】
輸入的第一行包含一個(gè)整數(shù)n,表示廣場(chǎng)是n邊形的(因此有n個(gè)頂點(diǎn))。
接下來n行,每行兩個(gè)整數(shù),依次表示n邊形每個(gè)頂點(diǎn)的坐標(biāo)(也就是說廣場(chǎng)邊緣拐彎的地方都在磚的頂角上。數(shù)據(jù)保證廣場(chǎng)是一個(gè)簡單多邊形。
【輸出格式】
輸出一個(gè)整數(shù),表示最多有多少市民可以在廣場(chǎng)跳舞。
【樣例輸入】
5
3 3
6 4
4 1
1 -1
0 4
【樣例輸出】7
【樣例說明】
廣場(chǎng)如圖1.png所示,一共有7塊完整的地板磚,因此最多能有7位市民一起跳舞。
【數(shù)據(jù)規(guī)模與約定】對(duì)于30%的數(shù)據(jù),n不超過100,橫縱坐標(biāo)的絕對(duì)值均不超過100。
對(duì)于50%的數(shù)據(jù),n不超過1000,橫縱坐標(biāo)的絕對(duì)值均不超過1000。
對(duì)于100%的數(shù)據(jù),n不超過1000,橫縱坐標(biāo)的絕對(duì)值均不超過100000000(一億)。
資源約定:
峰值內(nèi)存消耗 < 256M
CPU消耗? < 1000ms
請(qǐng)嚴(yán)格按要求輸出,不要畫蛇添足地打印類似:“請(qǐng)您輸入...” 的多余內(nèi)容。
所有代碼放在同一個(gè)源文件中,調(diào)試通過后,拷貝提交該源碼。
注意:不要使用package語句。不要使用jdk1.7及以上版本的特性。
注意:主類的名字必須是:Main,否則按無效代碼處理。
思路:有ACM經(jīng)驗(yàn)的大牛一定一眼就能看出來這是個(gè)凸包問題,當(dāng)然人家都不會(huì)看這種水平的題......好了,言歸正傳,想深入了解凸包問題的可以參考下面兩篇文章。
蠻力法在求解凸包問題中的應(yīng)用(JAVA)
分治法在求解凸包問題中的應(yīng)用(JAVA)--快包算法
單就這個(gè)題目,還達(dá)不到傳統(tǒng)凸包問題的難度,所以不了解也可以做。我們只需要判斷在所圍面積中的點(diǎn),它的右側(cè)、下側(cè)、右下側(cè)三個(gè)點(diǎn)是否也在范圍內(nèi)就可以了。如果都在范圍內(nèi)那么這個(gè)磚就是完整的,反之,不是完整的。
以下圖為例,我們可能不能漫無邊際的處理任意個(gè)點(diǎn),所以我們可以先找出所有坐標(biāo)中的x的上下限,y的上下限,即圖中紅色虛線所圍區(qū)域。之后對(duì)區(qū)域中的每個(gè)點(diǎn)進(jìn)行判斷。而如何判斷一個(gè)點(diǎn)是不是在所圍區(qū)域之內(nèi)呢?這里需要用到兩點(diǎn)式直線方程的概念,我們構(gòu)成邊界的點(diǎn)(x1,y1)(x2,y2),兩兩帶入兩點(diǎn)式,再帶入所判斷點(diǎn)(x,y)的一個(gè)坐標(biāo)dy,就可以求出另一個(gè)坐標(biāo)dx。而求出來的坐標(biāo)dx,如果在實(shí)際x的左側(cè),則不再范圍內(nèi);反之,在范圍內(nèi)。
完整代碼如下:
public class Point {int x;int y;public Point(int x, int y) {// TODO Auto-generated constructor stubthis.x = x;this.y = y;} }import java.util.Scanner;public class Main {static int cnt = 0;public static void main(String[] args) {Scanner in = new Scanner(System.in);int n = in.nextInt();Point[] points = new Point[n];int maxX = 0, minX = 99999999;int maxY = 0, minY = 99999999;for(int i = 0; i < n; i++) {int x = in.nextInt();int y = in.nextInt();points[i] = new Point(x, y);if(points[i].x > maxX) {maxX = points[i].x;}if(points[i].x < minX) {minX = points[i].x;}if(points[i].y > maxY) {maxY = points[i].y;}if(points[i].y < minY) {minY = points[i].y;}}for(int i = minX; i < maxX; i++) { //x的最小值到最大值for(int j = minY; j < maxY; j++) { //y的最小值到最大值//判讀右、下、右下的三個(gè)點(diǎn)是否都在范圍內(nèi)if(f(points, i, j) && f(points, i+1, j) && f(points, i, j+1) && f(points, i+1, j+1)) {cnt++;}}}System.out.println(cnt);}public static boolean f(Point[] points, int x, int y) {boolean flag = false;/*** 由于輸入時(shí)按順序的,所以計(jì)算還簡單了,只需要求出0點(diǎn)-1點(diǎn)、1點(diǎn)-2點(diǎn)、2點(diǎn)-3點(diǎn)、3點(diǎn)-4點(diǎn)、(4點(diǎn)-0點(diǎn))的斜率即可。* 其中4點(diǎn)-0點(diǎn)不好求,這里的做法非常巧妙,首先將j賦為4,先將4點(diǎn)和0點(diǎn)比較,之后 j=i,i++ ,避免了雙層嵌套還解決了回環(huán)的問題。* */int j = points.length - 1;for(int i = 0; i < points.length; i++) {// 各點(diǎn)y坐標(biāo)值的最小值 y坐標(biāo)值的最大值if(y > Math.min(points[i].y, points[j].y) && y <= Math.max(points[i].y, points[j].y)) {//兩點(diǎn)式獲得斜率,確定該點(diǎn)是否在范圍內(nèi)double temp = (double) points[i].x + (double)((( y- points[i].y)/ (double)(points[i].y - points[j].y)) * (double)((points[i].x - points[j].x)));if(temp < x) {flag = true;}}j = i;}return flag;} }
總結(jié)
以上是生活随笔為你收集整理的蓝桥杯第七届决赛JAVA真题----广场舞的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL中多表查询:左连接、右连接、内连接
- 下一篇: 衡量模块独立性的两个定性标准