题目的主要信息:

  • 输入 n 个整型数,统计其中的负数个数并求所有非负数的平均值,结果保留一位小数,如果没有非负数,则平均值为0
  • 输入的n不会给出,直接输入到文件尾

方法一:循环输入

具体做法:

可以用while循环输入直到没有数字为止,对于输入的每个数字统计输入的总数nn,判断数字是否是负数,负数也需要计数,然后如果是非负数则将其累加。

最后输出负数个数,如果负数个数等于总数说明没有非负数,输出0.0,否则计算非负数平均值。

alt

#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;
}

复杂度分析:

  • 时间复杂度:O(n)O(n),一共需要输入和判断nn次,计算是常数时间
  • 空间复杂度:O(1)O(1),只有常数个变量存储输入,无额外空间

方法二:递归输入

具体做法:

也可以将下一次输入看成是子问题,进入递归再一次输入然后统计总数、负数个数及非负数累加和,当读取遇到文件结束时跳出递归。

#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;
}

复杂度分析:

  • 时间复杂度:O(n)O(n),一共需要输入和判断nn次,计算是常数时间
  • 空间复杂度:O(n)O(n),递归栈深度为nn