题解:P5015 [NOIP2018 普及组] 标题统计

· · 题解

题目传送门

具体思想

翻了一圈,题解区里没有 getchar() 的做法,所以了提交一篇以提供新的思路。

很简单,由于 getline() 速度过慢, 所以我们可以在 getchar() (速度更快) 的基础上加以特判。

另外 getline() 需要用 string 类型,其空间占用是比 char 高上许多的。

具体实现。

Step 1。

先简简单单地搓出一个符合题意的代码。

#include <iostream> // getchar() 的头文件。

#define int long long // 防止炸精度。

using namespace std ; // 标准命名空间的调用。

char c ; // getchar() 输入的字符。
int ans ; // 答案记录。

signed main ( ) { // 开了 long long 主函数也得是 signed int 型。

  // 核心代码。
    while(c != '\n') 
        if(c != ' ') ans ++ ; // 根据题意,空格是不计入的,故特判不算入 ans。

    cout << ans << '\n' ; // 最后记得输出。

    return 0; 
}

经过运行,我们可以发现,这份代码成功地 TLE,0pts。

而问题也就出在了这里。

    while(c != '\n') 
        if(c != ' ') ans ++ ; // 根据题意,空格是不计入的,故特判不算入 ans。

这里的字符是一定要更新的,改成下面的样子。

// 核心代码。
    while(c != '\n') { // 当读到换行符时,一整行已经读入完毕。
        if(c != ' ') 
            ans ++ ; // 根据题意,空格是不计入的,故特判不算入 ans。
        c = getchar() ; // 无论如何都要记得更新。
    }

Step 2。

而修改之后呢?

#include <iostream> // getchar() 的头文件。

#define int long long // 防止炸精度。

using namespace std ; // 标准命名空间的调用。

char c ; // getchar() 输入的字符。
int ans ; // 答案记录。

signed main ( ) { // 开了 long long 主函数也得是 signed int 型。

// 核心代码。
    while(c != '\n') { // 当读到换行符时,一整行已经读入完毕。
        if(c != ' ') 
            ans ++ ; // 根据题意,空格是不计入的,故特判不算入 ans。
        c = getchar() ; // 无论如何都要记得更新。
    }

    cout << ans << '\n' ; // 最后记得输出。

    return 0; 
}

完美的 五彩斑斓,0pts。

问题也是很明显,这里。

// 核心代码。
while(c != '\n') { // 当读到换行符时,一整行已经读入完毕。
    if(c != ' ') {
        ans ++ ; // 根据题意,空格是不计入的,故特判不算入 ans。
        c = getchar() ; // 记得更新。
    }
}

一定要先读入第一个字符,具体如下。

// 核心代码。
    c = getchar() ; // 一定要先输入,否则 c 一开始的值为空。
    while(c != '\n') { // 当读到换行符时,一整行已经读入完毕。
        if(c != ' ') 
            ans ++ ; // 根据题意,空格是不计入的,故特判不算入 ans。
        c = getchar() ; // 无论如何都要记得更新。
    }

最终代码。


#include <iostream> // getchar() 的头文件。

#define int long long // 防止炸精度。

using namespace std ; // 标准命名空间的调用。

char c ; // getchar() 输入的字符。
int ans ; // 答案记录。

signed main ( ) { // 开了 long long 主函数也得是 signed int 型。

    // 核心代码。
    c = getchar() ; // 一定要先输入,否则 c 一开始的值为空。
    while(c != '\n') { // 当读到换行符时,一整行已经读入完毕。
        if(c != ' ') 
            ans ++ ; // 根据题意,空格是不计入的,故特判不算入 ans。
        c = getchar() ; // 无论如何都要记得更新。
    }

    cout << ans << '\n' ; // 最后记得输出。

    return 0; 
}

Plan 2。

当然我们也可以使用 do while() 来进行一定的压缩,代码如下。

#include <iostream> // getchar() 的头文件。

#define int long long // 防止炸精度。

using namespace std ; // 标准命名空间的调用。

char c ; // getchar() 输入的字符。
int ans ; // 答案记录。

signed main ( ) { // 开了 long long 主函数也得是 signed int 型。

    // 核心代码。
    do {
        c = getchar() ; // 记得更新。
        if(c != ' ') ans ++ ; // 根据题意,空格是不计入的,故特判不算入 ans。
    } while(c != '\n') ;

    cout << ans << '\n' ; // 最后记得输出。

    return 0; 
}

蒟蒻的第一篇题解,求过。