1060 Are They Equal (25 分)字串轉換浮點型數值
題目
If a machine can save only 3 significant digits, the float numbers 12300 and 12358.9 are considered equal since they are both saved as with simple chopping. Now given the number of significant digits on a machine and two float numbers, you are supposed to tell if they are treated equal in that machine.
Input Specification:
Each input file contains one test case which gives three numbers N, A and B, where N (<100) is the number of significant digits, and A and B are the two float numbers to be compared. Each float number is non-negative, no greater than , and that its total digit number is less than 100.
Output Specification:
For each test case, print in a line YES if the two numbers are treated equal, and then the number in the standard form
(d[1]>0 unless the number is 0); or NO if they are not treated equal, and then the two numbers in their standard form. All the terms must be separated by a space, with no extra space at the end of a line.
Note: Simple chopping is assumed without rounding.
Sample Input 1:
3 12300 12358.9
Sample Output 1:
YES 0.123*10^5
Sample Input 2:
3 120 128
Sample Output 2:
NO 0.12010^3 0.12810^3
解題思路
題目大意: 給你兩個數,以及一個正整數N,把這兩個數都轉換成保留位數為N的科學計數法,比較保留位數之後的資料,如果相等,輸出“YES”以及對應的數,如果不相等,輸出“NO”以及兩者的轉換結果。
解題思路: 這道題的難點在如何進行轉換,從幾個一般性的例子,我們總結規律。一般而言,有三種情況,一種是有小數點但是數比較大的,一種是小數點後的非常小的數,一種是沒有小數點的整數(可以看做第一種情況的特例)。
1. 第一步先確定小數點的位置,如果沒有小數點,那麼顯然是一個整數,其數值長度,即為指數值;
2. 確定了小數點位置之後,我們對數值字串進行原地操作,並且前面加上“0.”的字首;
3. 然後從新加的小數點後面開始遍歷,如果是0,說明之前是一個小於1的數,小數點需要右移,統計0的個數,同時把0移除;如果沒有0,說明之前是一個大於1的數,那麼其指數值是之前小數點的位置;
4. 保留精確位,如果此時的字串長度小於N位,需要補零,如果大於N,說明資料是足夠的,把多餘的部分刪掉即可。
該題結合string的erase和find函式,會大大節省程式碼長度,避免重複造輪子。
/*
** @Brief:No.1059 of PAT advanced level.
** @Author:Jason.Lee
** @Date:2018-12-25
** @Solution: https://blog.csdn.net/CV_Jason/article/details/85282890
*/
#include<iostream>
#include<string>
using namespace std;
void getmachine(int*e, string *str,int N)
{
int dot = (*str).find('.') ; // 尋找小數點的位置
if (dot != -1)// 如果存在小數點,那麼將該小數點消除
{
str->erase(dot, 1);
(*e) = dot; //同時記錄小數點的位置,該位置代表了進位數
}
else(*e) = str->size(); // 如果不存在小數點,說明輸入的是個整數
str->insert(0, "0.");// 在字元的首部插入 '0.'
// 尋找小數點的位置
dot = 2;// 因為已經插入了“0.”所以,從2開始算
// 如果存在許多0,那麼跳過這些0,並統計個數
while (str->size() > dot && (*str)[dot] == '0')
dot++;
dot -= 2;// 減去“ 0.”的長度,得到0的長度
str->erase(2, dot);// 消除“0.”之後所有的0
(*e) -= dot;// 記錄指數值
dot = str->size();
if (dot == 2)(*e) = 0;
N += 2;// 開始計算保留位數
if (dot > N) str->erase(N, dot - N +1);
else str->insert(dot, N - dot, '0');
}
int main()
{
string str[2];
int e[2];
int N;
cin >> N >> str[0] >> str[1];
getmachine(&e[0], &str[0],N);
getmachine(&e[1], &str[1],N);
if (e[0] == e[1] && str[0] == str[1])cout << "YES " << str[0] << "*10^" << e[0] << endl;
else cout << "NO " << str[0] << "*10^" << e[0] << " " << str[1] << "*10^" << e[1] << endl;
system("pause");
return 0;
}
總結
這道題看起來挺簡單,其實挺難的……