題目
DVD機在視頻輸出時,為了保護電視顯像管,在待機狀態會顯示"屏保動畫”,如下圖所示,DVD Logo在屏幕內來回運動,碰到邊緣會反彈:請根據如下要求,實現屏保Logo坐標的計算算法
1、屏幕是一個800 * 600像素的矩形,規定屏幕的左上角點坐標原點,沿橫邊向右方向為X軸,沿豎邊向下方向為Y軸
2、Logo是一個50 * 25像素的矩形,初始狀態下,左上角點坐標記做(x,y),它在X和Y方向上均以1像素/秒的速度開始運動;
3、遇到屏幕四個邊緣后,會發生鏡面反彈,即以45°碰撞邊緣,再改變方向以45°彈出;當Logo和四個角碰撞時,兩個邊緣同時反彈的效果是Logo會原路返回。
請編碼實現,t秒后Logo左上角點的坐標
輸入描述:
輸入3個數字,以空格分隔:x y t
第一個數字表示Logo左上角點的初始X坐標
第二個數字表示Logo左上角點的初始Y坐標:
第三個數字表示時間t,題目要求即求t秒后Logo左上角點的位置
輸出描述
輸出2個數字,以空格分隔:x y
第一個數字表示t秒后,Logo左上角點的X坐標
第二個數字表示t秒后,Logo左上角點的Y坐標
補充說明:
所有用例均保證:
1、輸入的x和y坐標會保證整個Logo都在屏幕范圍內,Logo不會出畫;
2、所有輸入數據都是合法的數值,且不會出現負數:
3、t的最大值為100000。
示例1
輸入:
0 0 10
輸出:
10 10
說明:
輸入樣例表示Logo初始位置在屏幕的左上角點,10s后,Logo在X和Y方向都移動了10像素,因此輸出10 10.
示例2
輸入:
500 570 10
輸出:
510 570
說明:
輸入樣例表示初始狀態下,Logo的下邊緣再有5像素就碰到屏幕下邊緣了,5s后,會與屏幕碰撞,碰撞后,斜向45彈出,又經過5s后,Logo與起始位置相比,水平移動了10像素,垂直方向回到了原來的高度。
思路
送分題,兩種方法:
- 程序模擬過程,得到t秒后的坐標
- 直接數學計算得出坐標
思路一:程序模擬過程
設一個數組dp=new int[]{1,1},dp[0]=1代表x向右移動1個單位長度,dp[1]代表y向下移動1個單位長度
根據題目要求:
當x到達邊界時(x+50=800),此時應該改變移動方向,即dp[0] = -1
同理可得,當y+25=60時,y也應該改變方向,即dp[1] = -1。
什么時候把方向再改回來呢?當x或者y為0時,應該將dp[0]、dp[1]修改為1
寫一個循環,直接可以得到t秒后x,y的新坐標。每秒x和y的變化過程為:x=x+dp[0];y=y+d[1]
思路二:數學計算
先不考慮越界情況,(x,y)經過t秒后得到的新坐標應該時(x+t,y+t)
考慮越界情況,x的最大值為750,y的最大值為575。x和y變化規律相同,以x為例說明:
當第一次越界時,比如x計算出來等于800,800%750=50,第一次越界應該向左反彈,所以實際的x為:750-50=700
當第二次越界時,比如x計算出來等于1560,1560%750=10,實際的運動軌跡應該是0-750-0-10,此時x的值就等于10
綜上:我們可以直接使用x+t得到x的新坐標,然后計算m,n的值:m=(x+t)/750;n=(x+t)%750
如果m%2=1,即奇數次越界,此時向左反彈,結果應該為750-n;
如果m%2=0,即偶數次越界,此時向右反彈,結果應該為n;
題解
package hwod;import java.util.Arrays;
import java.util.Scanner;public class ScreenProtect {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int[] nums = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();int x = nums[0], y = nums[1], t = nums[2];int[] res = screenProtect(x, y, t);for (int i = 0; i < res.length; i++) {if (i != 0) System.out.print(" ");System.out.print(res[i]);}}private static int[] screenProtect(int x, int y, int t) {int width = 800, height = 600;int[] dp = new int[]{1, 1};while (t-- > 0) {if (x == 0) {dp[0] = 1;}if (x +50 == width) {dp[0] = -1;}if (y == 0) {dp[1] = 1;}if (y +25 == height) {dp[1] = -1;}x += dp[0];y += dp[1];}return new int[]{x, y};}private static int[] screenProtect2(int x, int y, int t) {int max_x = 800-50, max_y = 600-25;x = x + t;y = y + t;int modx = x % max_x, mody = y % max_y;x = x / max_x % 2 == 1 ? max_x - modx : modx;y = y / max_y % 2 == 1 ? max_y - mody : mody;return new int[]{x, y};}
}
推薦
如果你對本系列的其他題目感興趣,可以參考華為OD機試真題及題解(JAVA),查看當前專欄更新的所有題目。