2010年2月23日 星期二

Problem 587 There's treasure everywhere!,找尋寶藏

假設你現在手上有一張藏寶圖,通常他會要你東南西北選一個方向走個幾步,再換個方向走,一直走到寶藏之所在地,你必須依照它給的指示去尋找寶藏。

現在你有一張這種藏寶圖,你必須馬上算出寶藏所在地,以及你到寶藏所在地之最短距離。開始以(0,0)做為起點,數字為移動格數,東西南北以英文字母 E、W、S、N 表示。例如輸入 4S.,也就是寶藏所在地在(0,-4),距離為 4。

此題以 double 定義 x、y 兩變數為目前所在地,當你初始化兩變數時,必須使它等於 1e-8(或更小的數),因為假設你定義 x = 0, y = 0;後,接著再去算乘法,會有誤差。

以下為主程式程式碼:
int caseNum = 0;
while (gets(str))
{
if (str[0] == 'E') break;
p.x = 1e-12, p.y = 1e-12;
int i, fIndex = 0;
double nowSteps = 1e-12;
char nowFace[2];
for (i = 0; str[i]; i ++)
{
if (str[i] >= '0' && str[i] <= '9')
nowSteps *= 10.0 ,nowSteps += str[i] - '0';
else if (isalpha(str[i]))
nowFace[fIndex] = str[i], fIndex ++;
else
{
if (fIndex == 1)
moveLinear (nowFace[fIndex - 1], nowSteps);
else
moveSlash (nowFace, nowSteps);
fIndex = 0;
nowSteps = 1e-12;
}
}

printf("Map #%d\n", ++caseNum);
printf("The treasure is located at (%.3lf,%.3lf).\n",p.x, p.y);
printf("The distance to the treasure is %.3lf.\n\n",sqrt(p.x*p.x + p.y*p.y));
}

而函式以及結構程式碼如下:
#define MAXLEN 250
char str[MAXLEN] = {"\0"};
struct Point
{
double x, y;
};
struct Point p;
void moveLinear (char f, double steps)
{
if (f == 'N') p.y += steps;
else if (f == 'E') p.x += steps;
else if (f == 'W') p.x -= steps;
else if (f == 'S')p.y -= steps;
}
void moveSlash (char f[], double steps)
{
int i;
steps *= sqrt(2) / 2;
for (i = 0; f[i]; i ++)
moveLinear(f[i] , steps);
}

By David.K

p587題目連結
回ACM題庫目錄
回首頁

沒有留言: