網(wǎng)站專業(yè)建設(shè)公司免費引流app下載
題目描述
繪圖機器的繪圖筆初始位置在原點(0,0),機器啟動后按照以下規(guī)則繪制直線:
- 嘗試沿著橫線坐標(biāo)正向繪制直線直到給定的終點E。
- 期間可以通過指令在縱坐標(biāo)軸方向進(jìn)行偏移,offsetY為正數(shù)表示正向偏移,為負(fù)數(shù)表示負(fù)向偏移。
給定了橫坐標(biāo)終點值E以及若干條繪制指令,請計算繪制的直線和橫坐標(biāo)軸以及X=E的直線組成圖形的面積。
輸入描述
首行為兩個整數(shù)N和E,表示有N條指令,機器運行的橫坐標(biāo)終點值E。
接下來N行,每行兩個整數(shù)表示一條繪制指令X offsetY,用例保證橫坐標(biāo)X以遞增排序的方式出現(xiàn),且不會出現(xiàn)相同橫坐標(biāo)X。
取值范圍:
- 0 < N <= 10000
- 0 <= X <= E <= 20000
- -10000 <= offsetY <= 10000
輸出描述
一個整數(shù),表示計算得到的面積,用例保證結(jié)果范圍在0到4294967295之內(nèi)。
解題思路
- 初始化變量:包括總面積、上一個點的橫坐標(biāo)和縱坐標(biāo)。
- 遍歷指令:對于每一條指令,計算當(dāng)前段與X軸圍成的面積,并累加到總面積中。
- 面積 = (當(dāng)前X - 上一個X) * |上一個Y|(因為上一個Y到當(dāng)前Y之間是一個矩形或梯形的高,而寬度是當(dāng)前X與上一個X的差)
- 注意,這里使用了絕對值來計算高度,因為面積總是正的。
- 處理最后一個段:如果最后一個點的X坐標(biāo)小于E,則需要計算最后一個段與X=E的直線圍成的面積。
- 輸出結(jié)果:輸出計算得到的總面積。
Java實現(xiàn)示例
import java.util.Scanner;public class DrawingMachineArea {public static void main(String[] args) {try (Scanner scanner = new Scanner(System.in)) {// 讀取N和Eint N = scanner.nextInt();int E = scanner.nextInt();// 輸入驗證if (N <= 0 || E <= 0) {throw new IllegalArgumentException("N 和 E 必須大于零");}// 初始化變量int lastX = 0; // 上一個點的橫坐標(biāo)int lastY = 0; // 上一個點的縱坐標(biāo)long totalArea = 0; // 總面積,使用long類型以防止溢出// 讀取指令并計算面積for (int i = 0; i < N; i++) {int currentX = scanner.nextInt();int offsetY = scanner.nextInt();// 輸入驗證if (currentX < 0 || currentX > E) {throw new IllegalArgumentException("currentX 必須在 [0, E] 范圍內(nèi)");}int currentY = lastY + offsetY; // 計算當(dāng)前Y坐標(biāo)// 計算當(dāng)前段與X軸圍成的面積int width = currentX - lastX;int height = Math.abs(currentY - lastY); // 使用絕對值計算高度// 溢出檢測if (width > Integer.MAX_VALUE / height) {throw new ArithmeticException("計算面積時可能發(fā)生溢出");}long segmentArea = (long)width * height; // 使用long類型進(jìn)行計算以防止溢出// 累加面積到總面積中totalArea += segmentArea;// 更新上一個點的坐標(biāo)lastX = currentX;lastY = currentY;}// 計算最后一個段與X=E的直線圍成的面積(如果有的話)if (lastX < E) {int width = E - lastX;long segmentArea = (long)width * Math.abs(lastY); // 使用long類型進(jìn)行計算以防止溢出// 溢出檢測if (totalArea > Long.MAX_VALUE - segmentArea) {throw new ArithmeticException("累加總面積時可能發(fā)生溢出");}totalArea += segmentArea;}// 輸出結(jié)果System.out.println(totalArea);} catch (Exception e) {System.err.println("發(fā)生錯誤: " + e.getMessage());}
}}
注意事項
- 輸入處理:確保輸入的格式正確,并按照題目描述的取值范圍進(jìn)行驗證(雖然題目要求不需要顯式驗證,但在實際編程中應(yīng)該考慮這一點)。
- 面積計算:在計算面積時,使用長整型(
long
)來防止溢出。這是因為當(dāng)N、E和offsetY的取值范圍較大時,單個段的面積可能會超過int
類型的最大值。 - 最后一個段:不要忘記計算最后一個段與X=E的直線圍成的面積(如果最后一個點的X坐標(biāo)小于E)。
- 輸出格式:輸出一個整數(shù)表示計算得到的面積,確保結(jié)果在題目給定的范圍內(nèi)內(nèi)。
為了提供一個運行示例,我將模擬一些輸入數(shù)據(jù),并展示如何使用上述Java代碼來計算繪圖機器繪制的直線與坐標(biāo)軸圍成的面積。由于我們不能直接在文本環(huán)境中運行代碼,我將通過描述輸入數(shù)據(jù)和預(yù)期輸出來模擬這個過程。
輸入數(shù)據(jù)示例
假設(shè)我們有以下輸入數(shù)據(jù):
4 10
2 3
4 -1
7 2
9 4
這表示:
- 有4條指令(N=4)。
- 橫坐標(biāo)終點值E=10。
- 指令依次為:
- 在X=2處,Y方向偏移+3(到達(dá)點(2,3))。
- 在X=4處,Y方向偏移-1(到達(dá)點(4,2))。
- 在X=7處,Y方向偏移+2(到達(dá)點(7,4))。
- 在X=9處,Y方向偏移+4(到達(dá)點(9,8))。
預(yù)期輸出
我們需要計算由這些點和X=10的直線圍成的面積。通過手動計算或運行代碼,我們可以得到以下面積:
- 從(0,0)到(2,3)的面積:2 * 3 = 6
- 從(2,3)到(4,2)的面積:2 * 1 = 2(注意高度是|3-2|=1)
- 從(4,2)到(7,4)的面積:3 * 2 = 6
- 從(7,4)到(9,8)的面積:2 * 4 = 8
- 從(9,8)到(10,8)的面積(與X=10相交):1 * 8 = 8
將這些面積相加,我們得到總面積:6 + 2 + 6 + 8 + 8 = 30。