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