本题是浙江理工大学ACM入队200题第八套中的K题

我们先来看一下这题的题面.

题面

题目描述

任意输入一个字符,判断其ASCII是否是奇数,若是,输出YES,否则,输出NO;

例如,字符A的ASCII值是65,则输出YES,若输入字符B(ASCII值是66),则输出NO

输入

输入为多组测试数据。

输入一个字符

输出

如果其ASCII值为奇数,则输出YES,否则,输出NO

样例输入

A

样例输出

YES


题目分析

这题其实没有任何难度,但是在acm群里问的还是挺多的,出问题的地方除了对换行的处理以外基本都是不知道在C中如何获得一个字符的ASCII码值.说到底是对char类型理解不深刻.

首先科普下什么是ASCII码(以下内容来自维基百科):

在计算机中,所有的数据在存储和运算时都要使用二进制数表示。例如,像a、b、c、d这样的52个字母(包括大写)以及0、1等数字还有一些常用的符号(例如*、#、@等)在计算机中存储时也要使用二进制数来表示,而具体用哪些二进制数字表示哪个符号,这就是编码。如果不同的计算机要想互相通信而不造成混乱,那么每台计算机就必须使用相同的编码规则,于是美国有关的标准化组织就推出了ASCII编码。

ASCII是由美国国家标准学会(American National Standard Institute,ANSI)制定的,使用标准的单字节字符编码方案,用于基于文本的数据。方案起始于50年代后期,在1967年定案。它最初是美国的标准,供不同计算机在相互通信时需共同遵守的西文字符编码标准。现已被国际标准化组织(International Organization for Standardization,ISO)定为国际标准(ISO/IEC 646),适用于所有拉丁字母。

我们知道,在C语言中存储一个字符的时候,我们使用char类型.但是不知道大家还记不记得,我们讨论数值类型的时候,我们也会说到char类型,说它是占用1个字节的数值型.

那这不矛盾吗?为啥同一个类型即是数值又是字符呢?

少年,你还是太年轻了,连波粒二象性都有了,区区一个char不能有"二象性"嘛?

在C中,如果你把char当成数值型使用(运算、用%d输出等),那么它就表现为一个数值,而当你把它作为一个字符型来使用时(作为字符串的一部分,用%c输出等),他就表现为一个字符.

比如如下代码:

	char c = 65;
printf("%c\n", c); // 输出字符a
printf("%d\n", (int)c); // 输出数值65(char没有自己专用格式字符,这里强制转型后用%d(强制转型仅仅是因为没有对应的格式字符而已,如果有一个对应的格式字符便可以直接输出这个数值了))
c = 'a' + 3; // 此处'a'表现为一个整数,值为a的ASCII码值(65),然后+3,结果为68,存入变量a中
printf("%d\n", (int)c); // 输出数值68
printf("%c\n", c); // 输出字符d('d'的ASCII码为67,所以前面的加法从字符的角度也可以理解成顺着ASCII码表往后第n个字符)

明白了char的这个特殊的"二象性",这题的代码就很好写了吧?没错,和对一个整数判断奇偶数一模一样,因为在取模时char表现为一个整数,而且就是这个字符的ASCII码值.


常见错误

解决完char的问题之后,欢迎来到下一个乱葬岗.

很多朋友按照上面的思路写完代码,信心满满提交上去,迎头一个WA,而且通过率还是0%.


不想丸辣!

原因相对比较复杂,我们这里比较浅显的说明一下.
在我们输入数据的时候,在一组数据输完之后,是通过按下回车来完成把数据输入进去的,对吧?(不打回车就不会读进去,不用管本质,接着看,下同)
然而很不幸的是,你键入的这个回车,当你使用`scanf`中使用`%c`时,它也被当成一个字符读进来.这会导致你的一次输入出现以下情况:



(^Zctrl+Z,表示输入结束,此时scanf会返回EOF)

由于异常读入的回车,导致一次输入两次输出(这个问题在Java中似乎也有,在不使用Scanner对象包装Systm.in的时候,也会异常读入输入结尾的换行)

那怎么解决捏?方法有很多,这边不展开讲了,就说一种最容易的.

在相信很多朋友都已经隐约感受到了,scanf的格式控制字符中,空格似乎不仅仅代表一个空格.事实上,在空格代表的是一个空白字符,空格属于一个空白字符,啥也没有也属于一个空白字符,而换行,也属于一个空白字符.所以我们可以通过使用" %c"来滤掉空格.

相信会用getchar函数的朋友这个时候要问了,不就是一个换行嘛?换行不就是\n嘛,一个字符,我直接用一个getchar把它读了不就行了.

思路确实可行,本地跑也是完全没有问题的,但是这样提交上去依旧是WA.因为你把换行想简单了.

实际上,换行不只有\n一种写法,也可能是\r\n,具体不展开,总之在这题的评测机输入中,你必须连续调用两次getchar函数才可以读掉换行,在评测机上AC.但是这会导致你本地跑不了(因为本地换行是\n,具体原因不解释).所以为什么不在scanf里打一个空格捏?简单又可行.

这个换行问题在后续还是会碰到的,特别是scanfgets一起使用的时候.这边建议有空学一学C++的cin对象,用cin对象即可完美解决换行的问题.不过记得还要学一下怎么关闭cinscanf的同步,不然代码的常数会比较大(人话:比较慢).


参考代码

下面给出了我自己做这道题时候的完整代码:

(仅作为参考,一定要自己写一下奥,作弊没意思,害人又害己)

#include <stdio.h>

int main()
{
char c;
while (~scanf(" %c", &c)) // 利用空格代表空白字符,去掉换行,同时保证没有换行时代码也是正确的.看不懂~(按位非)就写scanf(" %c", &c) != EOF
{
if (c % 2) // 即奇数(养成习惯不要==1,因为负奇数,虽然这里不可能会是负数)
{
printf("YES\n");
}
else // 即偶数
{
printf("NO\n");
}
}
return 0;
}

"正是我们每天反复做的事情,最终造就了我们,优秀不是一种行为,而是一种习惯" ---亚里士多德

这篇题解就到这里了,各位朋友如果有问题欢迎到acm成员群中提问哦!

「浙江理工大学ACM入队200题系列」问题 K: 零基础学C/C++84——奇偶ASCII值判断的更多相关文章

  1. 「浙江理工大学ACM入队200题系列」问题 L: 零基础学C/C++85——完美数

    本题是浙江理工大学ACM入队200题第八套中的L题 我们先来看一下这题的题面. 题面 题目描述 任何一个自然数的约数中都有1和它本身,我们把小于它本身的因数叫做这个自然数的真约数. 如6的所有真约数是 ...

  2. 「浙江理工大学ACM入队200题系列」问题 J: 零基础学C/C++83——宁宁的奥数路

    本题是浙江理工大学ACM入队200题第八套中的J题 我们先来看一下这题的题面. 题面 题目描述 宁宁参加奥数班,他遇到的第一个问题是这样的:口口口+口口口=口口口,宁宁需要将1~9 九个数分别填进对应 ...

  3. 「浙江理工大学ACM入队200题系列」问题 E: 零基础学C/C++78——求奇数的乘积

    本题是浙江理工大学ACM入队200题第八套中的E题 我们先来看一下这题的题面. 题面 输入 输入数据包含多个测试实例,每个测试实例占一行,每行的第一个数为n,表示本组数据一共有n个,接着是n个整数,你 ...

  4. 「浙江理工大学ACM入队200题系列」问题 L: 零基础学C/C++52——计算数列和2/1,3/2,5/3,8/5......

    本题是浙江理工大学ACM入队200题第五套中的L题 我们先来看一下这题的题面. 题面 题目描述 有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13,-- 计算这个数列的前n项和.注意: ...

  5. 「浙江理工大学ACM入队200题系列」问题 F: 零基础学C/C++39——求方程的解

    本题是浙江理工大学ACM入队200题第四套中的F题 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习惯,尤其是要利用好输入和输出样例. ...

  6. 「浙江理工大学ACM入队200题系列」问题 A: 零基础学C/C++34—— 3个数比较大小(冒泡排序与选择排序算法)

    本题是浙江理工大学ACM入队200题第四套中的A题,同时给出了冒泡排序和选择排序算法 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习 ...

  7. 「浙江理工大学ACM入队200题系列」问题 H: 零基础学C/C++18——三位数反转

    本题是浙江理工大学ACM入队200题第二套中的H题 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习惯,尤其是要利用好输入和输出样例. ...

  8. 「浙江理工大学ACM入队200题系列」问题 B: 零基础学C/C++12——求平均值

    本题是浙江理工大学ACM入队200题第二套中的B题 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习惯,尤其是要利用好输入和输出样例. ...

  9. [Python] 文科生零基础学编程系列二——数据类型、变量、常量的基础概念

    上一篇:[Python] 文科生零基础学编程系列--对象.集合.属性.方法的基本定义 下一篇: (仍先以最简单的Excel的VBA为例,语法与Python不同,但概念和逻辑需要理解透彻) p.p1 { ...

随机推荐

  1. java数组---数组的使用(打印,求和,最大值)

    public static void main(String[] args) { int[] arrays={1,2,3,4,5}; //打印该数组 for (int i = 0; i < ar ...

  2. Paperask一键获取A币

    又到了毕业季,查论文是一件很头疼的事情,网上免费查重检测力度又很一般┑( ̄Д  ̄)┍ 因为一次偶然同学推荐了解到这个网站,只要做新手任务就能得到很多积分,再进行抽奖就可以得到A币或者是至尊券可以免费使 ...

  3. KingbaseES R3 集群修改system用户密码方案

    方案说明: 对于kingbaseES R3集群修改system密码相比单机环境有一定的复杂性,需要修改的位置如下: 1)数据库中system用户密码,可以用alter user命令修改 2)在reco ...

  4. 【Java面试】面试遇到宽泛的问题,这么回答就稳了,谈谈你对Redis的理解

    "谈谈你对Redis的理解"! 面试的时候遇到这类比较宽泛的问题,是不是很抓狂? 是不是不知道从何开始说起? 没关系,今天我用3分钟教你怎么回答. 大家好,我是Mic,一个工作了1 ...

  5. Nessus-8.11.1-x64.msi安装包

    希望能给那些和我一样迷茫受挫的小伙伴们一些帮助,这玩意儿下载挺慢的,我把安装包分享出来,如果有博客园账号的,点个赞呗,CSDN那些用着别人的软件还要积分,呸! 08-18更新,截止到现在,已更新到最新 ...

  6. ES配置生成SSL使用的证书

    cd /usr/local/elasticsearch/bin/ ./elasticsearch-certgen ##################################### Pleas ...

  7. Elasticsearch: analyzer

    在今天的文章中,我们来进一步了解analyzer. analyzer执行将输入字符流分解为token的过程,它一般发生在两个场合: 在indexing的时候,也即在建立索引的时候 在searching ...

  8. Elasticsearch:shard 分配感知

  9. gitlab备份和恢复

    备份 生产环境下,备份是必需的.需要备份的文件有:配置文件和数据文件. 备份配置文件 配置文件包含密码等敏感信息,不要和数据文件放在一起. sh -c 'umask 0077; tar -cf $(d ...

  10. suse 安装mysql5.7

    1.上传包到home目录下 2.安装 1,解压下载的文件: tar -xvf mysql-5.7.29-1.sles12.x86_64.rpm-bundle.tar 解压后: 3.安装libatomi ...