【最优解法】1054 求平均值 (20分)_31行代码AC
立志用更少的代碼做更高效的表達
Pat乙級最優化代碼+題解+分析匯總——>傳送門
本題的基本要求非常簡單:給定 N 個實數,計算它們的平均值。但復雜的是有些輸入數據可能是非法的。一個“合法”的輸入是 [?1000,1000] 區間內的實數,并且最多精確到小數點后 2 位。當你計算平均值的時候,不能把那些非法的數據算在內。
輸入格式:
輸入第一行給出正整數 N(≤100)。隨后一行給出 N 個實數,數字間以一個空格分隔。
輸出格式:
對每個非法輸入,在一行中輸出 ERROR: X is not a legal number,其中 X 是輸入。最后在一行中輸出結果:The average of K numbers is Y,其中 K 是合法輸入的個數,Y 是它們的平均值,精確到小數點后 2 位。如果平均值無法計算,則用 Undefined 替換 Y。如果 K 為 1,則輸出 The average of 1 number is Y。
輸入樣例 1:
7
5 -3.2 aaa 9999 2.3.4 7.123 2.35
輸出樣例 1:
ERROR: aaa is not a legal number
ERROR: 9999 is not a legal number
ERROR: 2.3.4 is not a legal number
ERROR: 7.123 is not a legal number
The average of 3 numbers is 1.38
輸入樣例 2:
2
aaa -9999
輸出樣例 2:
ERROR: aaa is not a legal number
ERROR: -9999 is not a legal number
The average of 0 numbers is Undefined
我的解法
按字符串輸入, 設想出所有可能的特殊樣例判斷,如果沒有則輸出即可。以下情況為不合格。
注意:第4點和第5點非常容易忽略。
敲完代碼后沒有信心, 不斷的調試極限樣例,最后一發過,還是很開心的哈哈哈哈哈哈。 沒有白刷這么多天的題。
下面是大哥的解法, 主要利用了函數功能簡化操作。
大哥的解法
采用sscanf將字符串A轉化為浮點型變量。 再用sprintf將浮點型變量保存小數點后兩位,轉化為字符串B。 比較A和B在A的長度下是否相等, 如果不相等,則證明它不合法。
如果合法, 再判斷是否在[-1000,+1000]的區間內, 如果滿足,則保存,不滿足,則不合法。
我的代碼
#include<bits/stdc++.h> using namespace std; int main() { // while(1) {int n; cin>>n;double sum = 0; //和int numb = 0; //符合的數量 for(int i = 0; i < n; i++) {string s; cin>>s;bool fu = false, dian = false;bool flag = false;int len = s.length(); for(int i = 0; i < len; i++) {if(s[i] == '.' && dian == false) { //如果是第一個小數點,則開始下次循環 dian = true; continue;} else if(s[i] == '-' && fu == false) { //如果是第一個負號,則開始下次循環 fu = true; continue;}if(s[i] == '.' && dian == true) flag = true; //1、如果小數點出現了一次以上,則不合格 else if(s[i] == '-' && fu == true) flag = true; //2、如果負號出現了一次以上,則不合格 else if(s[i] != '.' && s[i] != '-' && (s[i] <'0' || s[i] >'9') ) flag = true; //3、如果既不是負號也不是小數點還不是0-9,則不合格 }if(s[0] == '.') flag = true; //4、特殊情況判斷if(s == "-") flag = true; //5、特殊情況判斷if(s[0]=='-' && s[1]=='.') flag = true; //如果以上條件都符合,則證明它是一個數字,下面篩選不合格的數字 stringstream ss(s); double x;ss >> x; if(x > 1000 || x < -1000) flag = true; //6、在區間之外,不合格 int find1 = s.find('.');if(find1 != s.npos) {string s1 = s.substr(find1+1);if(s1.length() > 2) flag = true; //7、小數點后超過兩位, 不合格} if(flag == false) { //如果以上情況皆無,則賦值 stringstream ss(s);double x;ss >> x; sum += x;numb++;} else cout << "ERROR: " << s << " is not a legal number" << '\n';} if(numb == 0) cout << "The average of 0 numbers is Undefined" << '\n';else if(numb == 1) printf("The average of 1 number is %.2f", sum);else printf("The average of %d numbers is %.2f", numb, sum/(numb*1.0));// } return 0; }大哥的代碼
#include<bits/stdc++.h> using namespace std; int main() {int n; cin>>n;double sum = 0; int numb = 0; //總和和合法 for(int i = 0; i < n; i++) {bool flag = false;char a[105], b[105];cin >> a;double x;sscanf(a, "%lf", &x);sprintf(b, "%.2lf", x);for(int i = 0; i < strlen(a); i++) {if(a[i] != b[i]) { //如果不相等 flag = true; break; }}if(flag==false && (x < -1000 || x > 1000)) flag = true;if(flag == true) printf("ERROR: %s is not a legal number\n", a);else {sum += x; numb++;}}if(numb == 0) printf("The average of 0 numbers is Undefined\n");else if(numb == 1) printf("The average of 1 number is %.2lf\n", sum);else printf("The average of %d numbers is %.2lf\n", numb, sum/numb);return 0; }耗時
每日一句
每一個不曾起舞的日子,都是對生命的辜負。
總結
以上是生活随笔為你收集整理的【最优解法】1054 求平均值 (20分)_31行代码AC的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【简洁代码】1053 住房空置率 (20
- 下一篇: 【简便代码+解析】1056 组合数的和