(本文是從我的舊博客遷移過來的)
問題地址:http://acm.timus.ru/problem.aspx?space=1&num=1258
前幾日在博客園看到這種在線測試的時候,有一種相見恨晚的感覺,於是隨便選了一道感興趣的題(No.1258:Pool)開始做。為了准確了解題的意思,我把題翻譯成中文了,這道題的原理和台球很相似(由於以前常玩可樂8,所以對台球的問題倍感親切)。但不知道為什麼出題人將台球問題說成了一個程序員撞牆的問題。下面是我翻譯後的,英語不好,譯錯的地方請見諒。
問題:
在午休的時候,程序員Vasechkin喜歡在他的矩形房間裡閒逛。他從他工作的地方開始溜達,直到他有了再開始工作的念頭才停止。我們已知當Vasechkin撞牆時,他的運動規律相當符合“入射角等於反射角”定律。並且Vasechkin走的路線是很直的線段。凶狠的辦公室主任決定找出他浪費了多少時間在溜達上。顯然Vasechkin走過的長度除以他的平均速度(事先測量)可得出所用的時間。所以必須知道這個長度!並且從Vasechkin的碰撞中能清楚的知道Vasechin的撞牆順序。可能還有更簡單的方法計算出程序員所浪費的時間,但是辦公室主任認為這是解決問題的最佳方法。
10 20
9 1
1 19
FLRLRB
52.8015出題人: Pavel Egorov



1 using System;
2 namespace ACM1258
3 {
4 class Program
5 {
6 static void Main()
7 {
8 System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
9
10 double result; //輸出
11 double sideX, sideY; //兩個直角邊
12 double X0,X1,Y0,Y1,W,D; //各個參數
13 string flrb; //撞牆順序
14 int coeffX0=0,coeffX1=0,coeffY0=0,coeffY1=0,coeffW=0,coeffD=0; //各個系數
15 bool checkLorR= true,checkForB= true; //是否檢查第一個LR、FB
16 bool LFirst= false,FFirst= false; //判斷第一個撞哪邊
17 bool FBpair= true,LRpair=true; //F與B、L與R的個數是否相等;
18
19 string[] temp;
20 temp = Console.ReadLine().Split(); //[0]:W [1]:D
21 W=Convert.ToDouble(temp[0]);
22 D=Convert.ToDouble(temp[1]);
23 temp = Console.ReadLine().Split(); //[0]:X0 [1]:Y0
24 X0=Convert.ToDouble(temp[0]);
25 Y0=Convert.ToDouble(temp[1]);
26 temp = Console.ReadLine().Split(); //[0]:X1 [1]:Y1
27 X1=Convert.ToDouble(temp[0]);
28 Y1=Convert.ToDouble(temp[1]);
29 flrb = Console.ReadLine();
30
31 for (int i = 0; i < flrb.Length; i++)
32 {
33 switch (flrb[i])
34 {
35 case 'F':
36 if (checkForB)
37 {
38 FFirst = true;
39 checkForB = false;
40 }
41 FBpair = !FBpair;
42 break;
43 case 'L':
44 if (checkLorR)
45 {
46 LFirst = true;
47 checkLorR = false;
48 }
49 LRpair = !LRpair;
50 break;
51 case 'R':
52 if (checkLorR)
53 {
54 LFirst = false;
55 checkLorR = false;
56 }
57 LRpair = !LRpair;
58 coeffW++;
59 break;
60 case 'B':
61 if (checkForB)
62 {
63 FFirst = false;
64 checkForB = false;
65 }
66 FBpair = !FBpair;
67 coeffD++;
68 break;
69 default:
70 break;
71 }
72 }
73
74 coeffX0 = LFirst ? 1 : -1;
75 coeffX1 = LRpair ? -coeffX0 : coeffX0;
76 coeffY0 = FFirst ? 1 : -1;
77 coeffY1 = FBpair ? -coeffY0 : coeffY0;
78
79 sideX = (coeffX0 * X0 + coeffX1 * X1) + coeffW * 2 * W;
80 sideY = (coeffY0 * Y0 + coeffY1 * Y1) + coeffD * 2 * D;
81
82 result = Math.Sqrt(sideX*sideX+sideY*sideY);
83 //result = ((int)(result * 10000)) / 10000.0; //這是直接捨去的,否則就是四捨五入
84 Console.WriteLine(result.ToString("F4"));
85 }
86 }
87 }
運行題中的測試用例結果:
