熱門文章

2026年2月27日 星期五

ZeroJudge 解題筆記:c092. 00587 - There's treasure everywhere!

作者:王一哲
日期:2026年2月27日


ZeroJudge 題目連結:c092. 00587 - There's treasure everywhere!

解題想法


我先用字典儲存各種方向縮寫對應的 1 個單位位移量,接下來再依照讀取到的測資計算東西向、南北向位移。我花最多時間的地方反而是在讀取測資,因為用數量不一定的逗號、句號分隔資料,反而比用空格分隔資料還要麻煩。用 C++ 解題時,如果用 float 會吃 WA,要用 double 才能 AC。

Python 程式碼


使用時間約為 7 ms,記憶體約為 2.9 MB,通過測試。
import sys

ca = 0
for line in sys.stdin:
    if line.rstrip() == "END": break
    ca += 1  # case 加 1
    if ca > 1: print()
    x, y = 0.0, 0.0  # 目前的位置
    dia = 1.0/(2**0.5)  # 對角線長度,2分之根號2
    dirs = {"N": (0.0, 1.0), "E": (1.0, 0.0), "S": (0.0, -1.0), "W": (-1.0, 0.0),
            "NE": (dia, dia), "NW": (-dia, dia), "SE": (dia, -dia), "SW": (-dia, -dia)}
    steps = line[:-2].split(",")  # 刪除最後的 .\n,再用 , 分割,存成串列
    for step in steps:  # 依序讀取每一步的距離、方向
        a = 0; d = ""  # 移動距離、方向
        for i, c in enumerate(step):  # 依序讀取 step 的字元,讀到英文字母為止
            if c.isalpha():
                a = int(step[:i])
                d = step[i:]
                break
        x, y = x + a*dirs[d][0], y + a*dirs[d][1]  # 更新位置
    print(f"Map #{ca:d}")
    print(f"The treasure is located at ({x:.3f},{y:.3f}).")
    print(f"The distance to the treasure is {(x*x + y*y)**0.5:.3f}.")


C++ 程式碼


這題如果使用 float,我在第 42 行會輸出錯誤的答案,改用 double 才過關。
您的答案為: The treasure is located at (-0.000,0.000).
正確答案為: The treasure is located at (0.000,0.000).

使用時間約為 1 ms,記憶體約為 340 kB,通過測試。
#include <iostream>
#include <iomanip>
#include <string>
#include <cmath>
#include <map>
#include <cctype>
using namespace std;

int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    int ca = 0;
    string line;
    while(getline(cin, line) && line != "END") {
        ca++;  // case 加 1
        if (ca > 1) cout << "\n";
        double x = 0.0, y = 0.0, dia = 1.0/sqrt(2);  // 目前的位置,2分之根號2
        map<string, double> dx = {{"N", 0.0}, {"E", 1.0}, {"S", 0.0}, {"W", -1.0},
                                  {"NE", dia}, {"NW", -dia}, {"SE", dia}, {"SW", -dia}};
        map<string, double> dy = {{"N", 1.0}, {"E", 0.0}, {"S", -1.0}, {"W", 0.0},
                                  {"NE", dia}, {"NW", dia}, {"SE", -dia}, {"SW", -dia}};
        int a = 0;  // 移動距離
        string s = "", d = "";  // 移動距離、方向
        for(char c : line) {  // 依序讀取每一步的距離、方向
            if (c == ',' || c == '.') {  // 如果 c 是 ,. 結算前一步
                x += 1.0*a*dx[d];  // 更新位置
                y += 1.0*a*dy[d];
                s.clear();
                d.clear();  // 清空 s, d
            } else if (isdigit(c)) {  // 如果 c 是數字
                s += c;  // 更新 c
            } else if (isalpha(c)) {  // 如果 c 是字母
                a = stoi(s);  // s 轉成整數存入 a
                d += c;  // 更新 d
            }
        }
        //if (x > -0.0000000001 && x < 0.0000000001) x = fabs(0.0);  // 不加也能過
        //if (y > -0.0000000001 && y < 0.0000000001) y = fabs(0.0);  // 不加也能過
        cout << "Map #" << ca << "\n";
        cout << "The treasure is located at (" << fixed << setprecision(3) << x << "," << y << ").\n";
        cout << "The distance to the treasure is " << sqrt(x*x + y*y) << ".\n";
    }
    return 0;
}


沒有留言:

張貼留言