题目的主要信息:
- 输入 n 个整型数,统计其中的负数个数并求所有非负数的平均值,结果保留一位小数,如果没有非负数,则平均值为0
- 输入的n不会给出,直接输入到文件尾
方法一:循环输入
具体做法:
可以用while循环输入直到没有数字为止,对于输入的每个数字统计输入的总数,判断数字是否是负数,负数也需要计数,然后如果是非负数则将其累加。
最后输出负数个数,如果负数个数等于总数说明没有非负数,输出0.0,否则计算非负数平均值。
#include<iostream>
#include<iomanip>
using namespace std;
int main(){
int val;
int count = 0; //统计负数个数
double sum = 0; // 统计非负数和
int n = 0; //统计输入的总数
while(cin >> val){
n++; //计算输入的总个数
if(val < 0)
count++; //统计负数个数
else //累加非负数和
sum += val;
}
cout << count << endl;
if(count == n) //没有非负数
cout << "0.0" << endl;
else{
cout.setf(ios::fixed); //不足位自动补齐
cout << fixed << setprecision(1) << sum / (double)(n - count) << endl; //计算均值
}
return 0;
}
复杂度分析:
- 时间复杂度:,一共需要输入和判断次,计算是常数时间
- 空间复杂度:,只有常数个变量存储输入,无额外空间
方法二:递归输入
具体做法:
也可以将下一次输入看成是子问题,进入递归再一次输入然后统计总数、负数个数及非负数累加和,当读取遇到文件结束时跳出递归。
#include<iostream>
#include<iomanip>
using namespace std;
void recursion(int& num, int& count, double& sum, int& n){ //递归输入
if(scanf("%d", &num) == EOF) //直到读取遇到文件结束
return;
n++;
if(num < 0) //统计负数个数
count++;
else //非负数和累加
sum += num;
recursion(num, count, sum, n); //进入下一次读取
}
int main(){
int val;
int count = 0; //统计负数个数
double sum = 0; // 统计非负数和
int n = 0; //统计输入的总数
recursion(val, count, sum, n);
cout << count << endl;
if(count == n) //没有非负数
cout << "0.0" << endl;
else{
cout.setf(ios::fixed); //不足位自动补齐
cout << fixed << setprecision(1) << sum / (double)(n - count) << endl; //计算均值
}
return 0;
}
复杂度分析:
- 时间复杂度:,一共需要输入和判断次,计算是常数时间
- 空间复杂度:,递归栈深度为