作业讲解
金字塔
本题考查了循环的嵌套
#include <stdio.h>
int main()
{
long long n, i, j;
// scanf()如果读到文件末尾, 会返回 EOF, EOF 在 C 语言中的值为 -1
// 返回值的意思是, a = scanf(), scanf() 的返回值会赋给 a
// while(~scanf("%lld", &n))
while(scanf("%lld", &n) != EOF)
{
// 循环每一行
for(i = 1; i <= n; i ++ )
{
// 输出空格
for(j = 1; j <= n - i; j ++ )
printf(" ");
// 输出*
for(j = 1; j <= 2 * i - 1; j ++ )
printf("*");
// 换行, puts("")会输出双引号内的字符并换行
puts("");
}
}
return 0;
}
字符数
本题考查多组输入, 题目中明确只有一行字符, 因此只需要考虑空格即可
#include<stdio.h>
int main()
{
char c;
long long sum = 0;
// getchar()每次只会读入一个字符, 包括换行符和空格
// 检测读到文件末尾
while ((c = getchar()) != EOF)
{
// 因为题目中说了输入只有一行, 所以只需要考虑将空格过滤掉
if(c != ' ') sum++;
}
// 输出检测到了多少个字符
printf("%lld", sum);
return 0;
}
体检
本题每次训练只剩下一半的人还在, 而且合格的人向上取整, 所以不合格的其实就是除 2 向下取整, 因此循环除 2 就可以了
#include <stdio.h>
int main()
{
long long a,ans;
scanf("%lld", &a);
while(a)
{
// 每一次都有一半(向上取整)的人合格, 只剩下 a / 2 的人
a /= 2;
// 记录多少次
ans ++;
}
printf("%lld\n", ans);
return 0;
}
售票员
本题中, 看到 10 元就可以直接卖票, 看到 30 元需要拿两张10 元找零, 100 元要找 90 元钱
#include <stdio.h>
int main()
{
// a, b, c 用于记录手上有几张 10 元, 几张 30 元, 几张 100 元
// temp 用于记录当前来买票的客人拿着多少钱
long long a = 0, b = 0, c = 0, temp;
while(scanf("%lld", &temp) != EOF)
{
// 10 元的话, 皆大欢喜, 给票收钱就可以了
if(temp == 10)
{
a ++;
}
// 30 元的话, 需要有两张 10 元来找零
else if(temp == 30)
{
if(a >= 2)
{
a -= 2;
b ++;
}
else
{
puts("NO");
// return 0 可以直接结束这个函数
return 0;
}
}
// 如果拿了 100 元
else
{
// tempb 用于存找零用几张 30 元
long long tempb;
// 如果 b 大于 3, 用 3 张 30 元, 这里注意, 优先用 30 元找零, 因为 30 只能用于找 100
if(b > 3)
{
tempb = 3;
}
else
{
tempb = b;
}
// 如果能找的开
if(tempb * 3 + a >= 9)
{
b -= tempb;
a -= 9 - tempb * 3;
}
else
{
puts("NO");
return 0;
}
}
}
// 如果没有在中间出问题
puts("YES");
return 0;
}
区间判断回文数
判断一个数是不是回文数, 把这个数倒过来就可以了
把一个123456 变成 654321 然后判断和原来的数一不一样就行了
123321会变成123321, 显然, 这两者完全一样, 那这就是一个回文数
#include <stdio.h>
int main()
{
long long n, i, num, j, a, b;
scanf("%lld%lld", &a, &b);
// 检查从 a 到 b 的每一个数字
for(i = a; i <= b; i ++ )
{
long long m = i;
num = 0;
// 将 i 倒过来
while (m)
{
num = num * 10 + m % 10;
m /= 10;
}
if(num == i)
{
printf("%lld\n", num);
}
}
return 0;
}
常见问题及debug方法
在写代码的时候, 大家可能都出现了非常多的问题, 请不需要有什么负担, 这对初学者而言很正常, 让我们一起来解决它们
多组输入在DEVC++的测试中结束不了
当我们使用下面这行代码时, 我们会发现这个程序是结束不了的
while(scanf("%lld", &n) != EOF)
使用 Ctrl + Z 就可以结束输入
数据太大
我们通常可以这么去记, 对 2e9 以下的数据, int 就可以
对 4e18 的数据, long long 可以解决
debug
进入下一部分之前, 我们做一个小小的游戏
我们来看一下下面这段代码有什么问题
#include <stdio.h>
int main(){
int a, i, j, stuScore;
int n = 10;
for (i = 1; i <= 10; i ++ )
{
for (j = 1; j <= 10; j ++ )
{
printf("%lld", stuscore);}
}
}
}
数据类型
int %d
long long %lld
float %f
double %lf
char %c
{}
不知道在写代码的时候你们有没有出现这种错误, {}由于各种各样的原因没有一一匹配
为了避免这一问题, 我们通常用两种风格来书写代码
第一种:
#include <stdio.h>
int main()
{
int a, i, j;
int n = 10;
for (i = 1; i <= 10; i ++ )
{
for (j = 1; j <= 10; j ++ )
{
printf("%d", i);
}
}
return 0;
}
第二种
#include <stdio.h>
int main(){
int a, i, j;
int n = 10;
for (i = 1; i <= 10; i ++ ){
for (j = 1; j <= 10; j ++ ){
printf("%lld", i);
}
}
return 0;
}
这两种代码风格同样的简洁, 大家可以自行选择, 如果选择一种, 请尽可能长期的使用一种, 这可以让你避免这种类似的错误
小驼峰命名法
当标识符是一个单词的时候,首字母小写
示例:name
当标识符有多个单词的时候,第一个首字母是小写,其他的首字母都是大写
示例:myStudentCount ,myFirstName
大驼峰命名法
当标识符只有一个单词的时候,首字母大写
示例: Name
当标识符有多个单词的时候,所有单词的首字母均是大写,比如:
示例: MyStudentCount , MyFirstName
驼峰命名法一般是用于变量名或函数名等多个单词连接在一起的情况,因为高低起伏像骆驼一样,所以名为驼峰命名法。
变量初始化
有时我们记录答案是加到一个变量上的, 如果没有初始化, 非全局变量的默认值并非是0, 这种错误很常见, 如果你觉得自己的代码没有计算错误, 那么不如检查以下有没有初始化变量
跳过右括号!!!
由于在写代码的时候打一个左括号(包括大中小)就会冒出来一个完整的左右括号, 所以我们通常在打完()后按一下方向键的向右键
但是要按方向键可能耽误我们的打字速度, 因为方向键通常不能很顺手的按倒, 因此, 当你发现自己出现了这个困扰的时候, 请尝试我下面所说的两种方案
1, 按右括号
大多数成熟的写代码环境和打字环境种直接按右括号就能跳过, 不如自己尝试一下吧?
2, insert模式
有时候按右括号并不会跳过, 但你发现键盘上有一个 insert 键, 切换至 insert 模式后我们只需要管自己要打的字是什么, 因为它会吞并掉后面的字符, 不如尝试一下?
;
每一行的结尾都要检查有没有 ;
这个问题很小, 但是这在一开始很常见, 请养成好这个习惯, 当然, 这个问题很容易被检查到, 对吗?
时间超限
Time limit exceeded
出现这种情况, 大多是由于死循环, 检查循环判断即可
但如果没有问题的话, 请检查你的代码思路是否有问题, 或者是否有更优的解法
除0
在需要用到除法的时候请注意, 不要在 / 后面放一个可能变成 0 的变量, 这本身是错误的
课堂练习
写代码最重要的就是写代码, 我准备了一场课堂练习, 在两点开始, 我会在两点四十开始讲