白駿-10158号(アリ)


質問元:https://www.acmicpc.net/problem/10158
質問する
2 Dメッシュ空間があり、長さ
  • 、幅w、長さh.このメッシュは下図のように左下角(0,0),右上角(w,h)である.この空間の座標(p,q)にアリが1匹置かれています.アリは一定の速度で右上45度方向に移動し始めた.最初に(p,q)から出発したアリは1時間後に(p+1,q+1)に転移した.しかし、この速度で移動すると、エッジインタフェースにぶつかると、同じ速度で反射移動します.

  • 上図6×四格図は,(4,1)から出発したばかりのアリの移動経路を示している.最初(4,1)のアリは2時間後(6,3),8時間後(0,1)であった.そのアリが最初に(5,3)いると、1時間ごとに(6,4)、(5,3)、(4,2)、(3,1)移動します.

  • 大きさw×hのメッシュ空間では,最初に(p,q)から出発したアリのt時間後の位置(x,y)を算出して出力する必要がある.アリは決して疲れないと仮定して、同じ速度で移動します.

  • 問題ではwとhは自然数であり,範囲は2≦w,h≦40000であった.アリの初期位置pとqも自然数であり,範囲はそれぞれ0
  • import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.StringTokenizer;
    
    public class Main {
    
        public static void main(String[] args) throws IOException {
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            StringTokenizer tokenizer = new StringTokenizer(reader.readLine());
            
            int W = Integer.parseInt(tokenizer.nextToken()); // 열
            int H = Integer.parseInt(tokenizer.nextToken()); // 행
            tokenizer = new StringTokenizer(reader.readLine());
            int X = Integer.parseInt(tokenizer.nextToken()); // x 좌표
            int Y = Integer.parseInt(tokenizer.nextToken()); // y 좌표
            tokenizer = new StringTokenizer(reader.readLine());
            int T = Integer.parseInt(tokenizer.nextToken()); // 시간
    
            int resultX = (X + T) % (W * 2);
            int resultY = (Y + T) % (H * 2);
    
            if (resultX > W) resultX = W * 2 - resultX;
            if (resultY > H) resultY = H * 2 - resultY;
    
            System.out.println(resultX + " " + resultY);
        }
    
    }
  • 最初は単純な思考と解答だったが、様々な状況を考慮しなかったため失敗した.
  • はまったく方法が思いつかず、グーグルで知った方法は、移動する行と列がそれぞれ2倍ずつ計算されていることだ.このようにアリは一端から出発し、他端を撮影して起点(2ワット移動、2時間移動)に戻ると、残りの演算で簡単に得ることができます.残りがWより大きい場合,アリは逆に行い,適切に処理した.