前言一、1108 Finding Average (20 分)二、分析
AC代码: 三、1109 Group Photo简说总结
前言
大年初一了,也又是一年生日,又是普通的聚餐一天,晚上拜访亲戚回来顺手刷了一下Pat1108和1109,有些小问题回顾一下
提示:以下是本篇文章正文内容,下面案例可供参考
一、1108 Finding Average (20 分)题目
The basic task is simple: given N real numbers, you are supposed to
calculate their average. But what makes it complicated is that some of
the input numbers might not be legal. A legal input is a real number
in [−1000,1000] and is accurate up to no more than 2 decimal places.
When you calculate the average, those illegal numbers must not be
counted in.
Input Specification:
Each input file contains one test case. For each case, the first line
gives a positive integer N (≤100). Then N numbers are given in the
next line, separated by one space.
Output Specification:
For each illegal input number, print in a line ERROR: X is not a legal
number where X is the input. Then finally print in a line the result:
The average of K numbers is Y where K is the number of legal inputs
and Y is their average, accurate to 2 decimal places. In case the
average cannot be calculated, output Undefined instead of Y. In case K
is only 1, output The average of 1 number is Y instead.
Sample Input 1:
7 5 -3.2 aaa 9999 2.3.4 7.123 2.35
Sample Output 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
Sample Input 2:
2 aaa -9999
Sample Output 2:
二、分析ERROR: aaa is not a legal number
ERROR: -9999 is not a legal number
The average of 0 numbers is Undefined
题目大意就是将给定序列中的不合法元素除去,将剩下合法的数值求平均值,精度到小数点后两位。
所以核心问题就转移到如何除去不合法元素。
这本身是一个很简单的问题,我们可以自己手写方法用来判定排除所有的不合法情况,如下:
bool isNumber(string str){
//消除负号影响
if(str[0] == '-') str = str.substr(1);
//起始不可能为小数点
if(str[0] == '.') return false;
//0开头则必然后跟小数点或正好为0;
if(str[0] == '0' && str[1] != '.' && str.length() > 2) return false;
//定义小数点的位置和个数
int pointIndex = 0, pointCount = 0;
for(int i = 0 ; i < str.length(); i++){
if(str[i] <= '0' && str[i] >='9') return false;
else if(str[i] == '.'){
pointIndex = i;
pointCount ++;
}
}
//如果小数点多于一个或者小数点精度大于2则不符合
if(pointCount > 1 || ((str.length() - (pointIndex + 1)) > 2 && pointCount == 1)) return false;
return true;
}
但是这仅完成了对数值类型的判断,还需要对越界进行数值范围的判断。但是由于输入的是字符串,首先要将符合数值规则的字符串转化成数值类型,方法有很多,比如可以利用字符串流ostringstream 和 istringstream,或者atof等自带函数,然后就是就是参考了柳神的代码想起来的利用sscanf函数进行了类型转换。(sscanf函数位于stdio.h中)
sscanf()会将参数str的字符串根据参数format字符串来转换并格式化数据。格式转换形式请参考scanf()。转换后的结果存于对应的参数内,利用它可以从字符串中取出整数、浮点数和字符串等等。
#include三、1109 Group Photo简说#include #include using namespace std; int cnt; double sum, temp; int n; bool isNumber(string str){ if(str[0] == '-') str = str.substr(1); if(str[0] == '.') return false; if(str[0] == '0' && str[1] != '.' && str.length() > 2) return false; //定义小数点的位置和个数 int pointIndex = 0, pointCount = 0; for(int i = 0 ; i < str.length(); i++){ if(str[i] == '.'){ pointIndex = i; pointCount ++; continue; } else if(str[i] < '0' || str[i] >'9') return false; } if(pointCount > 1 || (pointCount == 1 && (str.length() - (pointIndex + 1)) > 2) ) return false; return true; } int main(){ cin >> n; char a[50], b[50]; while(n--){ scanf("%s", a); //利用sscanf把字符串转化成所需的数据类型 sscanf(a, "%lf", &temp); int flag = isNumber(a); //若是数值类型,则比较数值类型的大小,超出范围也不符合 if( !flag || temp > 1000 || temp < -1000){ printf("ERROR: %s is not a legal numbern", a); }else{ cnt++; sum += temp; } } if(cnt == 1) //注意审题,别落了1的情况。 printf("The average of 1 number is %.2f", sum); else if(cnt > 1){ printf("The average of %d numbers is %.2fn", cnt, sum/cnt); }else{ printf("The average of 0 numbers is Undefinedn"); } return 0; }
由于晚上回来太晚,1109就不写题解了,也是一道模拟题,题目比较长,耐心看就行了,只要理清楚怎么去排位置,如何从中间向两头从大到小排就行了,本就是先集合按要求排序,从有序集合中从大到小挑出需要人数,从中间向两边分两组,一组从center + 1向右排,一组从center - 1向左排(有点抽象,建议简单模拟一下样例就会发现,排序后最大值放在中间,然后从第二大开始,每次间隔一个从有序集合中挑出一个人往左排,到指定人数就停止,从第三大开始也每次间隔一个从有序集合中挑出一个人向右排,直到一排人数满就行了,进行下一排)
AC代码:
#include#include #include using namespace std; struct node{ string name; int height; }; int cmp(struct node a, struct node b) { return a.height != b.height ? a.height > b.height : a.name < b.name; } int main(){ int n, k; cin >> n >> k; vector persons; for(int i = 0 ; i < n; i++){ node temp; cin>> temp.name; cin>> temp.height; persons.push_back(temp); } sort(persons.begin(),persons.end(), cmp); int cnt = 0, row = k; int m; while(row){ if(row == k){ m = n - (n / k) *(k - 1); }else{ m = n / k; } vector ans(m); ans[(m/2)] = persons[cnt]; int j = m /2 - 1; for(int i = cnt + 1 ; i < cnt + m ; i += 2){ ans[ j-- ] = persons[i]; } j = m / 2 + 1; for(int i = cnt + 2; i < cnt + m; i += 2){ ans[j++] = persons[i]; } cout << ans[0].name; for(int i = 1; i < m; i++){ cout<<" "<
总结 对于c++ 的各种头文件我并没有研究过,对于我来说,c++只是用于考试的工具,java才是常用,说实话有点感觉可惜(因为由于上学年的悲惨的考研经历,让我java的知识也忘了大半,最后还大概率需要二战,有点凄凉)加油吧,总是能挤出时间的,练题的同时也要不断回顾javase和之前的学的框架,毕竟先要把毕设搞定,然后最后冲一次考上研吧,加油!!(争取之后有时间的话,题解会增加java的AC代码,当然视情况而定,毕竟java有点卡时限)



