CSP-202309-2-坐標變換(其二)
關鍵點總結
1.輸入輸出的同步關閉,以加快I/O操作的速度
- 這一點還是很重要的,本題代碼如果不進行輸入輸出的同步關閉會時間超限。
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
2.設置輸出的小數精度
#include <iostream>
#include <iomanip> // 導入設置精度所需的庫
using namespace std;int main() {double number = 3.14159265; // 這是我們要格式化的浮點數cout << std::fixed << setprecision(4); // 設置數字格式為固定小數點,并保留小數點后四位cout << number << endl; // 輸出結果return 0;
}
3.累計存儲k和theta減少時間開銷
- 本題中對坐標變換(比如縮放和旋轉)操作的累計處理,其中
k
代表縮放比例,theta
代表旋轉角度。在這種處理方法中,k
和theta
的值不是獨立存儲每次操作的結果,而是累積地存儲從初始狀態到當前狀態的變換結果。 通過累積地存儲變換參數(k
和theta
),程序可以避免在每次查詢時重復計算從初始狀態到當前狀態的所有變換。這樣,當進行大量的查詢時,可以大大減少計算時間,提高程序的效率。在這種方法中,如果需要計算從一個狀態到另一個較早狀態的逆變換,可以簡單地通過比較兩個狀態的累積參數來實現。這比單獨存儲每次變換的結果更為簡便,因為不需要單獨計算逆變換。
解題思路
-
結構體定義:定義結構體
MyOperate
來存儲每次操作的k
(縮放因子)和θ
(旋轉角度)。 -
主函數初始化:在
main
函數中,首先設置了輸入輸出的同步關閉,以加快I/O操作的速度。然后讀入操作的總數n
和查詢的總數m
。接下來,初始化一個MyOperate
類型的向量optList
來存儲每次操作后的k
和θ
值。向量的大小設置為n+1
,以便存儲初始狀態(即第0次操作,此時k=1
且θ=0
)和之后每次操作的結果。 -
輸入操作處理:對于每次輸入的操作,根據操作的類型(縮放或旋轉),更新結構體數組
optList
中對應的k
和θ
值。對于縮放操作,更新k
值并保持θ
不變;對于旋轉操作,更新θ
值而保持k
不變。新的值是基于前一次操作的結果計算得出的。 -
查詢處理:對于每次查詢,讀入起始操作編號
start
、結束操作編號end
以及查詢點的初始坐標(x, y)
。使用start
和end
來確定查詢范圍內的總縮放因子和總旋轉角度,即從start
到end
這段操作對點的總影響。然后根據這個總縮放因子和總旋轉角度來計算點的最終位置。 -
坐標變換:使用總縮放因子
kTemp
和總旋轉角度thetaTemp
對點(x, y)
進行變換。先對點進行縮放,然后根據旋轉角度進行旋轉。旋轉時需要用到cos(thetaTemp)
和sin(thetaTemp)
來更新點的坐標。 -
輸出結果:最后,輸出經過所有操作后點的新坐標。使用
setprecision(4)
來設置輸出的小數精度。
完整代碼
#include <iostream>
#include <vector>
#include <cmath>
#include <iomanip> // 導入設置精度所需的庫
using namespace std;struct MyOperate
{double k;double theta;
};int n, m;int main() { ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin >> n >> m;vector<MyOperate>optList(n + 1);// 初始化for (int i = 0; i < n + 1; i++){optList[i].k = 1, optList[i].theta = 0;}// 輸入操作for (int i = 1; i <= n; i++){double optFlag, optNum;cin >> optFlag >> optNum;// kif (optFlag==1){optList[i].k = optList[i - 1].k * optNum;optList[i].theta = optList[i - 1].theta;}// thetaelse if (optFlag == 2){optList[i].theta = optList[i - 1].theta + optNum;optList[i].k = optList[i - 1].k;}}// 輸入查詢for (int i = 0; i < m; i++){int start, end;double x, y;cin >> start >> end >> x >> y;double kTemp = optList[end].k / optList[start - 1].k;double thetaTemp = optList[end].theta - optList[start - 1].theta;double awsX, awsY;awsX = x * kTemp, awsY = y * kTemp;double awsX_temp = awsX, awxY_temp = awsY;awsX = awsX_temp * cos(thetaTemp) - awxY_temp * sin(thetaTemp);awsY = awsX_temp * sin(thetaTemp) + awxY_temp * cos(thetaTemp);cout << fixed << setprecision(4);cout << awsX << " " << awsY << endl;}return 0;
}