巨集的陷阱
1.0s 256M多數的人在學 C++ 的 #define 的用法時(此語法中文翻為「巨集」),會錯把 #define F(X) 當作函式來用。
拿以下問題為例:
給你二維平面上的兩個點 \(A\) 和 \(B\),\(A\) 的座標為 \((A_x,A_y)\),\(B\) 的座標為 \((B_x, B_y)\),請計算點 \(A\) 和點 \(B\) 兩個點間直線距離的平方。
我們知道,兩個點的距離公式為 \(\sqrt{(A_x - B_x)^2 + (A_y - B_y)^2}\),所以平方後的結果為 \((A_x - B_x)^2 + (A_y - B_y)^2\),此公式出現了兩次平方的計算。有些人會選擇把平方用「巨集」來表示,寫成程式碼如下:
#include<iostream>
using namespace std;
#define SQR(X) X * X
int main() {
int A_x, A_y, B_x, B_y;
cin >> A_x >> A_y >> B_x >> B_y;
cout << SQR(A_x - B_x) + SQR(A_y - B_y) << endl;
return 0;
}
但這樣子答案卻是錯的,例如,當點 \(A\) 為 \((2, 1)\),點 \(B\) 為 \((-2, -2)\) 時,此份程式碼會輸出 \(13\),但答案應該是 \((2-(-2))^2 + (1 - (-2))^2 = 25\)。
這是因為編譯器會把 \(SQR(A\_x - B\_x) + SQR(A\_y - B\_y)\) 取代為 \(A\_x - B\_x * A\_x - B\_x + A\_y - B\_y * A\_y - B\_y\)。正確的巨集寫法應為如下
#define SQR(X) ((X) * (X))
本題要大家寫一份程式碼來實驗巨集的錯誤寫法和正確寫法,輸入會給你點 \(A\) 和點 \(B\) 的座標,請依序輸出以上所列的錯誤程式碼的將會輸出的答案以及正確的答案。
輸入格式
輸入只有一行,包含四個整數,依序為 \(A_x, A_y, B_x, B_y\)。輸入滿足 \(-10,000 \le A_x, A_y, B_x, B_y \le 10,000\)。
輸出格式
輸出一行包含兩個整數,第一個整數是題敘裡錯誤的程式碼輸出的答案,第二個數字是正確的答案。
評分說明
此題佔 \(20\) 分。
範例輸入 1
2 1 -2 -2
範例輸出 1
13 25
登入後即可撰寫程式並提交評測。
登入