「浙江理工大学ACM入队200题系列」问题 K: 零基础学C/C++84——奇偶ASCII值判断
本题是浙江理工大学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`时,它也被当成一个字符读进来.这会导致你的一次输入出现以下情况:
(^Z
是ctrl+Z
,表示输入结束,此时scanf
会返回EOF
)
由于异常读入的回车,导致一次输入两次输出(这个问题在Java中似乎也有,在不使用Scanner
对象包装Systm.in
的时候,也会异常读入输入结尾的换行)
那怎么解决捏?方法有很多,这边不展开讲了,就说一种最容易的.
在相信很多朋友都已经隐约感受到了,scanf
的格式控制字符中,空格似乎不仅仅代表一个空格.事实上,在空格代表的是一个空白字符,空格属于一个空白字符,啥也没有也属于一个空白字符,而换行,也属于一个空白字符.所以我们可以通过使用" %c"
来滤掉空格.
相信会用getchar
函数的朋友这个时候要问了,不就是一个换行嘛?换行不就是\n
嘛,一个字符,我直接用一个getchar
把它读了不就行了.
思路确实可行,本地跑也是完全没有问题的,但是这样提交上去依旧是WA.因为你把换行想简单了.
实际上,换行不只有\n
一种写法,也可能是\r\n
,具体不展开,总之在这题的评测机输入中,你必须连续调用两次getchar
函数才可以读掉换行,在评测机上AC.但是这会导致你本地跑不了(因为本地换行是\n,具体原因不解释).所以为什么不在scanf
里打一个空格捏?简单又可行.
这个换行问题在后续还是会碰到的,特别是scanf
和gets
一起使用的时候.这边建议有空学一学C++的cin
对象,用cin
对象即可完美解决换行的问题.不过记得还要学一下怎么关闭cin
和scanf
的同步,不然代码的常数会比较大(人话:比较慢).
参考代码
下面给出了我自己做这道题时候的完整代码:
(仅作为参考,一定要自己写一下奥,作弊没意思,害人又害己)
#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值判断的更多相关文章
- 「浙江理工大学ACM入队200题系列」问题 L: 零基础学C/C++85——完美数
本题是浙江理工大学ACM入队200题第八套中的L题 我们先来看一下这题的题面. 题面 题目描述 任何一个自然数的约数中都有1和它本身,我们把小于它本身的因数叫做这个自然数的真约数. 如6的所有真约数是 ...
- 「浙江理工大学ACM入队200题系列」问题 J: 零基础学C/C++83——宁宁的奥数路
本题是浙江理工大学ACM入队200题第八套中的J题 我们先来看一下这题的题面. 题面 题目描述 宁宁参加奥数班,他遇到的第一个问题是这样的:口口口+口口口=口口口,宁宁需要将1~9 九个数分别填进对应 ...
- 「浙江理工大学ACM入队200题系列」问题 E: 零基础学C/C++78——求奇数的乘积
本题是浙江理工大学ACM入队200题第八套中的E题 我们先来看一下这题的题面. 题面 输入 输入数据包含多个测试实例,每个测试实例占一行,每行的第一个数为n,表示本组数据一共有n个,接着是n个整数,你 ...
- 「浙江理工大学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项和.注意: ...
- 「浙江理工大学ACM入队200题系列」问题 F: 零基础学C/C++39——求方程的解
本题是浙江理工大学ACM入队200题第四套中的F题 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习惯,尤其是要利用好输入和输出样例. ...
- 「浙江理工大学ACM入队200题系列」问题 A: 零基础学C/C++34—— 3个数比较大小(冒泡排序与选择排序算法)
本题是浙江理工大学ACM入队200题第四套中的A题,同时给出了冒泡排序和选择排序算法 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习 ...
- 「浙江理工大学ACM入队200题系列」问题 H: 零基础学C/C++18——三位数反转
本题是浙江理工大学ACM入队200题第二套中的H题 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习惯,尤其是要利用好输入和输出样例. ...
- 「浙江理工大学ACM入队200题系列」问题 B: 零基础学C/C++12——求平均值
本题是浙江理工大学ACM入队200题第二套中的B题 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习惯,尤其是要利用好输入和输出样例. ...
- [Python] 文科生零基础学编程系列二——数据类型、变量、常量的基础概念
上一篇:[Python] 文科生零基础学编程系列--对象.集合.属性.方法的基本定义 下一篇: (仍先以最简单的Excel的VBA为例,语法与Python不同,但概念和逻辑需要理解透彻) p.p1 { ...
随机推荐
- SyncFusion安装和使用
1.Visual Studio 继承 Visual Studio菜单栏 → 扩展 → 扩展管理 → 搜索框中搜索 "Syncfusion Windows",单击 "Win ...
- docker的volume和bind mount究竟有什么区别?
不知道你在使用docker的时候,有没有注意到volume mount和bind mount的使用? 进一步说,他们之间的区别到底是什么? 接下来的内容,我们就为你揭开他们的神秘面纱. 相同之处 首先 ...
- vue2和vue3的区别?
vue2和vue3的主要区别在于以下几点: 1.生命周期函数钩子不同 2.数据双向绑定原理不同 3.定义变量和方法不同 4.指令和插槽的使用不同 5.API类型不同 6.是否支持碎片 7.父子组件之间 ...
- django_day03
django_day03 Django的view(视图) CBV和FBV FBV:function based view 基于函数的视图 CBV:class based view 基于类的视图 fro ...
- k8s 网络持久化存储之StorageClass(如何一步步实现动态持久化存储)
StorageClass的作用: 创建pv时,先要创建各种固定大小的PV,而这些PV都是手动创建的,当业务量上来时,需要创建很多的PV,过程非常麻烦. 而且开发人员在申请PVC资源时,还不一定有匹配条 ...
- docker 匿名和具名挂载
匿名挂载,只指定容器内了,没指定容器外 -v 容器内路径 docker run -d -P --name nginx01 -v /etc/nginx nginx #-P 随机映射端口 ; -v 不指定 ...
- Haproxy部署及控制台使用手册
一.介绍 1.简介 HAProxy是一个使用C语言编写开源软件,提供高可用,负载均衡,以及基于TCP(四层)和HTTP(七层)的应用程序代理: HAProxy特别适用于那些负载特大的web站点,这些站 ...
- KingbaseES V8R3集群维护案例之---在线添加备库管理节点
案例说明: 在KingbaseES V8R3主备流复制的集群中 ,一般有两个节点是集群的管理节点,分为master和standby:如对于一主二备的架构,其中有两个节点是管理节点,三个数据节点:管理节 ...
- git revert总结
git revert git revert 是一种创建一次新的commit 来回退某次或某几次commit的一种方式 命令 // 创建一个新的commit,这个commit会删除(下面)commit- ...
- Andrej Karpathy | 详解神经网络和反向传播(基于 micrograd)
只要你懂 Python,大概记得高中学过的求导知识,看完这个视频你还不理解反向传播和神经网络核心要点的话,那我就吃鞋:D Andrej Karpathy,前特斯拉 AI 高级总监.曾设计并担任斯坦福深 ...