#jitoa#【c语言学习与刷题感悟】 原创
本博客由 金陵科技学院-开放原子开源社 杨鑫编写
学习c语言已经将近3个多月,从最初的一窍不通到现在自己能编码,感觉这三个月里学习到许多知识,听完翁恺老师以及acwing上的课程,刷了acwing上的题目,深有感悟。以下将对c语言的一些章节发表一下我的学习与刷题感悟。
1.变量、输入输出、表达式与顺序语句
【AcWing 1. A + B】
题目描述
输入两个整数,求这两个整数的和是多少。
输入格式
输入两个整数A,B,用空格隔开
输出格式
输出一个整数,表示这两个数的和
数据范围
0≤A,B≤108
实现代码:
#include <stdio.h>
int main()
{
int m,n;
scanf("%d %d",&m,&n);
printf("%d",m+n);
return 0;
}
这是c语言最基础的题目,这题主要是让我们熟练掌握c语言的变量、输入输出、表达式与顺序语句的语法知识,同时我们还学到了整型int的输入输出是%d,浮点型float的输入输出是%f,双浮点型double的输入输出是%lf,字符型输入输出是%c。
2.判断语句
【AcWing 665. 倍数】
题目描述
读取两个正整数值A和B。
如果其中一个是另一个的整数倍,则输出 Sao Multiplos,否则输出 Nao sao Multiplos。
输入格式
共一行,两个整数A和B。
输出格式
按题目所述,输出结果。
数据范围
0<A,B<100
实现代码:
#include <stdio.h>
int a,b;
int main()
{
scanf("%d %d",&a,&b);
if (a % b == 0 || b % a == 0){
printf("Sao Multiplos");
}else{
printf("Nao sao Multiplos");
}
return 0;
}
这道主要让我们掌握判断语句的基本结构以及相关语法知识,学到常用比较运算符(1) 大于 >(2) 小于 <
(3) 大于等于 >=(4) 小于等于 <=(5) 等于 ==(6) 不等于 !=,以及条件表达式(1) 与 &&(2) 或 ||
(3) 非 !
3.循环语句
【AcWing 724. 约数】
题目描述
输入一个整数 N,按照从小到大的顺序输出它的全部约数。
输入格式
一个整数 N。
输出格式
输出全部约数,每个约数占一行。
数据范围
1≤N≤1000
实现代码:
#include <stdio.h>
int main()
{
int n;
scanf("%d",&n);
for (int i = 1; i <= n; i ++)
{
if (n % i == 0)
printf("%d\n",i);
}
return 0;
}
本题主要是对循环结构的运用,同时其中也有对数学知识中约数的应用。在其他循环结构中学到了跳转语句1. break:可以提前从循环中退出,一般与if语句搭配。2. continue:可以直接跳到当前循环体的结尾。作用与if语句类似。
4.数组
【7-8 螺旋方阵】
题目描述
所谓“螺旋方阵”,是指对任意给定的N,将1到N×N的数字从左上角第1个格子开始,按顺时针螺旋方向顺序填入N×N的方阵里。本题要求构造这样的螺旋方阵。
输入格式:
输入在一行中给出一个正整数N(<10)。
输出格式:
输出N×N的螺旋方阵。每行N个数字,每个数字占3位。
实现代码:
#include<stdio.h>
int main(){
int n,i=0,j,c=0;
scanf("%d",&n);
int k=0,l=n-1;
int a[n][n];
while(k<=l){
for( j=k ;j<=l;j++) a[k][j]=++c;
for(i=k+1;i<=l;i++) a[i][l]=++c;
for(j=l-1;j>=k;j--) a[l][j]=++c;
for(i=l-1;i>k ;i--) a[i][k]=++c;
k++;l--;
}
for(i=0;i<n;i++){
for(j=0;j<n;j++)
printf("%3d",a[i][j]);
printf("\n");
}
}
本题考查了数组的语法知识,本题中在利用数组的同时也应用了while以及for循环,k<=l是为了以一次圆周为循环,下面4个for循环先是向右,然后向下,接着向左,最后向上完成一次循环,然后实现代码。然后应用双循环输出结果矩阵。
5.字符串
【7-17 h0129. 最长单词】
题目描述
一个以’.’结尾的简单英文句子,单词之间用空格分隔,没有缩写形式和其它特殊形式,求句子中的最长单词。
输入格式:
输入这个简单英文句子,长度不超过500。
输出格式:
该句子中最长的单词。如果多于一个,则输出第一个。
实现代码:
#include <stdio.h>
#include <string.h>
int main()
{
char s[511];
gets(s);
int len = strlen(s);
int i;
int count=0;
int t;
int max;
for(i=0;i<len;i++){
if(s[i]==' '){
count=0;
}else{
count++;
}
if(count>max){
max=count;
t=i;
}
}
for(int j=t-max+1;j<t;j++){
printf("%c",s[j]);
}
return 0;
}
本题考查了字符串的语法内容,本题中int len=strlen(s)是用来计算字符数组s的长度,这需要#include <string.h>头文件。同时字符串还有一些其他知识点:
1.字符串就是字符数组加上结束符’\0’。可以使用字符串来初始化字符数组,但此时要注意,每个字符串结尾会暗含一个’\0’字符,因此字符数组的长度至少要比字符串的长度多1。
2.以下函数需要应用这个头文件
#include <string.h>
(1) strlen(str),求字符串的长度
(2)strcmp(a, b),比较两个字符串的大小,a < b返回-1,a == b返回0,a > b返回1。这里的比较方式是字典序!
(3) strcpy(a, b),将字符串b复制给从a开始的字符数组。
3.每个常用字符都对应一个-128 ~ 127的数字,二者之间可以相互转化。注意:目前负数没有与之对应的字符。
常用ASCII值:‘A’- 'Z’是65 ~ 90,‘a’ - 'z’是97 - 122,0 - 9是 48 - 57。
字符可以参与运算,运算时会将其当做整数。
6.函数
【AcWing 842. 排列数字】
题目描述
给定一个整数 n,将数字 1∼n排成一排,将会有很多种排列方法。
现在,请你按照字典序将所有的排列方法输出。
输入格式
共一行,包含一个整数 n。
输出格式
按字典序输出所有排列方案,每个方案占一行。
数据范围
1≤n≤7
实现代码:
#include <iostream>
using namespace std;
const int N=7;
int n;
int a[N];
bool b[N];
void dfs(int u){
if(u==n){
for(int i=0;i<n;i++){
printf("%d ",a[i]);
}
printf("\n");
return;
}
for(int i=1;i<=n;i++){
if(!b[i]){//判断
b[i]=true;
a[u]=i;//赋值
dfs(u+1);
b[i]=false;//返回值
}
}
}
int main()
{
cin>>n;
dfs(0);
return 0;
}
这题我是用的c++,这题用了函数的知识,是一个经典的dfs题目。
解题思路:因为本题要按照顺序大小排列数字,因此这里的递归要按照顺序,从1开始到n从大到小依次遍历。又因为每一个数字都要进行输出,因此还需要对每个位置上的数字进行遍历。
解题过程:
const int N=7;
int n;
int a[N];
bool b[N];
首先定义一个全图变量。
void dfs(int u){}
接着设计一个dfs函数。
if(u==n){
for(int i=0;i<n;i++){
printf("%d ",a[i]);
}
printf("\n");
return;
}
然后设计一个循环结束的条件,并且输出结果。
for(int i=1;i<=n;i++){
if(!b[i]){//判断
b[i]=true;
a[u]=i;//赋值
dfs(u+1);
b[i]=false;//返回值
}
}
然后先判断,赋值,递归。注意:结束要返还值。
int main()
{
cin>>n;
dfs(0);
return 0;
}
最后设计一个主函数。