ACM入门第一讲

一:引言

  • 为什么学习编程?

为了“搬砖”。

  • 那为什么要打 “ACM”?

当然是为了更好地“搬砖”。

其实编程几乎已经成为当今大学生必备的一个技能,就像几年前掌握“EXCEL、WORD”一样;那么,你怎么在这些人中脱颖而出,特别是科班生,(哪个专业的人都会c++,那你出来干啥)?所以你就得打“ACM”——当然这不是充分必要条件,但是打“ACM”绝对是一条~~“不归路”~~,不会让你后悔的一条路,你会在大四感叹“辛亏俺当时打了ACM”。、

言归正传:

二:the “hello world” vision of c++

#include<iostream>

using namespace std;

int main()
{
    cout<<"hello world"<<endl;
    return 0;
}

这样第一个程序就写好了。

接下来我们开始正式入门c++

三:简单介绍一下c++程序结构

还是拿 hello world 举例子

#include<iostream> 这个学名叫做“头文件”,其实就是一个工具箱,里面的好多东西,c++创始人或者一些大佬(就那些看似是艺术家的美国老头)给你写好了,你只需要会用就行。不同的头文件会包含不同的工具,但是有一个万能头文件#include<bits/stdc++.h>,它包含几乎所有我们竞赛要用到的头文件;但是千万不要在课堂上用。

using namespace std;这个和上一个差不多,学名叫做“命名空间”,也是人家写好了的东西,直接用就行。

main 一条程序的入口,非常重要,程序就是从这个开始执行的,而且一个程序只能由一个main函数。

return 0 程序结束的标志,其实新标准可以选择不写。

先暂时了解这么多,初学阶段没有必要深究,只需要写程序的时候写不错。

四:变量类型(ACM常用的)

变量:程序中用来存储数据的

类型存储大小值范围
bool1 字节true(1)或者false(0)
char1 字节- 2 7 2^7 27 2 7 − 1 2^7-1 271 或 0 到 2 8 2^8 28 (不同编译器不同) --ASCII码
int4 字节- 2 31 2^{31} 231 2 31 2^{31} 231-1转化成10进制,大概在1e9级别
long long8 字节- 2 63 2^{63} 263 2 63 2^{63} 263-1转化成10进制,大概在1e18级别
unsigned long long8 字节 0 0 0 2 64 2^{64} 264
double8 字节2.3E-3081.7E+308
long double16 字节3.4E-49321.1E+4932

变量的使用:

int a = 0,b = 1;
int a,b;  //如果不初始化,编译器可能会随机赋值。
double a,b;
bool flag = false;
bool flag = 1;

五:输入输出

对于一个变量,你既可以在程序中手动赋值,也可以从键盘中读入。

1.C版本 ——scanfprintf

格式化输入输出

格式解释读入类型
%c单个字符:读取下一个字符。char
%d十进制整数int
%x、%X十六进制整数。int
%lld十进制整数long long
%f浮点数double
  • 输入
int a;
scanf("%d",&a);
double b;
scanf("%f",&b)
int c;
scanf("%X",c);

//格式化输入
//假如题目要求你读入a,b,c三个数字,计算加和,但是给出的样式是 
1,2,3
6
int a,b,c;
scanf("%d,%d,%d",&a,&b,&c);

  • 输出
//从键盘中读入一个数字,并输出
int a;
scanf("%d",&a);
printf("%d",a);//注意,输入有&,输出没有
//格式化和scanf是差不多的。

//如果是输出两个,以空格或者,隔开
int a,b;
printf("%d %d",a,b);
printf("%d,%d\n",a,b);
//`\n`——换行符



//顺便提一句,在程序里出现的所有标点符号尽量使用英文,因为。。。
//双引号引起来的可以使用中文,其他地方使用中文符号,你是编译不过去滴。
//新手一般常常犯这个错误,找了半天,程序逻辑没有问题,一度怀疑人生,而且你还用的是`VC++6.0`
//而且你英语还不好,还看不懂人家给你提示的错误;然后你就被劝退了


//常常遇到的保留小数的问题
double a,b;
scanf("%f%f",&a,&b);
//保留两位小数
printf("%.2f %.2f\n",a,b);

2.c++版本

相比之下,c++ 输入输出就略微简单些了

int a,b;
cin>>a>>b;
cout<<a<<" "<<b<<endl;
//这里的endl相当于`\n`,换行符

double a,b;/char a,b;
cin>>a>>b;

//虽然麻烦,但是c++也可以实现输出保留几位小数
cout<<fixed<<setpresion(2)<<a<<endl;

注意:

cin遇到空格或者换行符会停止,所以要灵活根据题目输入要求选择不同的输入方式,事半功倍。

  • 不同点

速度不同,虽然cin可以通过以下的几行代码加快速度。

ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);

但是,当数据范围达到1e5乃至1e6级别,还是凸显出C语言的优势——

为什么要追求速度,因为我们竞赛的题目都要求要在秒级跑完,最多的也就是几乎到10000ms,所以说如果你不重视你程序的时间复杂度,你就会得到:(不过T着T着就A了)

(img-JJTsiept-1632487174649)

六、运算符

1.算术运算符

加减乘除 取模 自增 自减

int a = 10,b = 11;
int c = a + b;// 21
c = a - b;    // -1
c = a * b;    // 110
c = b % a;    // 1
//除法
//正常来讲 11 ➗ 10 应该等于 1.1.
//但是在计算机中,如果 a,b 都定义成整型变量,那么 a/b 会将得到的结果自动向下取整
c = a / b; // =1
//如果想得出1.1
double a = 10,b = 11;
double c = a/b;
//或者
int a = 11,b = 10;
double c = a*1.0/b;
//不要问为什么,这是美国佬定的标准

关于自增,自减,是不少同学学习 C C C 语言遇到的第一个坎,其实根本没有那么玄乎,就是自身加一,自身减一,但是由于和其他运算结合的时候,优先级不同,所以 ++a, 和 a++ 会返回不同的结果,我觉得没有必要看课本上说的那些东西,就是说他们单独(一定是单独)出现时,作用是一样的。

2.关系运算符

比较大小,或者等于不等于

运算符描述
==检查两个操作数的值是否相等,如果相等则条件为真。
!=检查两个操作数的值是否相等,如果不相等则条件为真。
>检查左操作数的值是否大于右操作数的值,如果是则条件为真。
<检查左操作数的值是否小于右操作数的值,如果是则条件为真。
>=检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。
<=检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。
3.逻辑运算符

在计算机中不是真就是假,不存在“没有绝对的真,没有绝对的假”这一说法。

运算符描述
&&称为逻辑与运算符。如果两个操作数都 true,则条件为 true。
||称为逻辑或运算符。如果两个操作数中有任意一个 true,则条件为 true。
!称为逻辑非运算符。用来逆转操作数的逻辑状态,如果条件为 true 则逻辑非运算符将使其为 false。
  • 短路特性

|| 会拥有一个“短路特性”,a,b 是一个表达式,如果 a 的逻辑值为 1,那么将直接返回 true,表达式 b 将不再计算。

4.位运算符

计算机中所有的数据都是以二进制存储的。

位运算符作用于位,并逐位执行操作。&、 | 和 ^ 的真值表如下所示:

&:都为 1,结果才为 1

|:有一个为 1,结果就为 1

~0变成11变成0

^:不同为1 ,相同为0

pqp & qp | qp ^ q
00000
01011
11110
10011

假设变量 A 的值为 60,变量 B 的值为 13,则:

60:0011 1100

13:0000 1101

运算符描述实例
&按位与操作,按二进制位进行"与"运算。(A & B) 将得到 12,即为 0000 1100
|按位或运算符,按二进制位进行"或"运算。(A | B) 将得到 61,即为 0011 1101
^异或运算符,按二进制位进行"异或"运算。不同为1,相同为 0(A ^ B) 将得到 49,即为 0011 0001
~取反运算符,按二进制位进行"取反"运算。(~A ) 将得到 -61,即为 1100 0011
<<二进制左移运算符。将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)。A << 2 将得到240,即为 1111 0000
>>二进制右移运算符。将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。A >> 2 将得到 15,即为 0000 1111
5.赋值运算符
运算符实例
=C = A + B 将把 A + B 的值赋给 C
+=C += A 相当于 C = C + A
-=C -= A 相当于 C = C - A
*=C *= A 相当于 C = C * A
/=C /= A 相当于 C = C / A
%=C %= A 相当于 C = C % A
<<=C <<= 2 相当于 C = C << 2
>>=C >>= 2 相当于 C = C >> 2
&=C &= 2 相当于 C = C & 2
^=C ^= 2 相当于 C = C ^ 2
|=C |= 2 相当于 C = C | 2
6.其他运算符
  • 三目运算符

a?b:c a , b , c a,b,c a,b,c 均可为表达式

如果 a a a 的逻辑值为 1 1 1,则执行 b b b ; 否则执行 c c c

  • 取地址符 & \& &
int *a = &p;

(img-D6BQjuEv-1632487174651)

7.各种运算符的优先级

类似于,小学学过的,先算乘除,后算加减,有括号的,先算括号。

两种办法:~~1.记表;~~2.加括号。

在做题中可能会遇到的问题:

1.溢出

就是你想表示的数字不在该变量类型所能表示的范围。

例如:

int a = 2147483647(2^31-1);
int c = a + 100;

(img-y497H0vF-1632487174652

解决办法就是用 l o n g   l o n g long ~long long long

实际做题过程中,会牵扯到数据范围的问题, i n t int int 大概在 1 e 9 1e9 1e9 l o n g   l o n g long~long long long 大概在 1 e 18 1e18 1e18 的范围内,所以看到 1 e 9 1e9 1e9 的范围的时候,你第一想法应该是开 l o n g   l o n g long ~long long long 1 e 18 1e18 1e18 更不用说了,1e5你就应该稍微估计一下了,否则的话——“爆ll了”。

2.类型转换

这一部分其实最常用的是 A S C I I ASCII ASCII 码的处理。‘a’ 对应的是 0110 0001——97,‘A’ 对应的是 0100 0001——65,’0‘ 对应的是0011 0000——48

char test = 'a';
cout<<test<<endl;
cout<<int(test)<<endl;
for(int i = 1;i <= 10;i ++){
    cout<<(test+i)<<endl;
}

(img-qb0IieAJ-1632487174654)

还有一个比较常用的技巧就是把 int 转化为 long long

int a,b;
cin>>a>>b;
long long c = a*1ll + b*1ll;

七:条件控制语句

  • 伪代码
if(表达式结果为真){
	内容1}
else{
    内容2}
  • e x a m p l e example example
int a;
cin>>a;
if(a <20 && a > 10){
    cout<<a<<endl;
}
else {
    cout<<a+10<<endl;
}

也可以多个:

int a;
cin>>a;
if(a < 30 && a > 20){
    cout<<"1:"<<a<<endl;
}
else if(a >= 10){
    cout<<"2:"<<a<<endl;
}
else {
    cout<<"3:"<<a<<endl;
}

前面讲到的逻辑运算符,常常作为 if(表达式) 的判断条件。

  • 例子1

输入三个数,输出最大的那个。这是某年的新生赛的签到题,很多人没签上。。。

先思考一下该怎么做 ?

int a,b,c;
cin>>a>>b>>c;
int ans = a;
if(ans <= b){
    ans = b;
}
if(ans <= c){
    ans = c;
}
cout<<ans<<endl;
  • 例子2

裁判规定,总分100分;

获得92.8分及92.8分以上的选手获得金牌;

在92.8分以下但在85.6分及85.6分以上的选手获得银牌;

在85.6分以下,但在82.1分及82.1分以上的选手获得铜牌;

分数在82.1分以下的选手不获奖。

请从键盘读入一名选手的分数,判断他应该获得哪个奖项?

如获得金牌,请输出“jin”,银牌请输出“yin”,铜牌请输出“tong”,没有获得奖项请输出“sorry”。

#include<iostream>

using  namespace std;

int main()
{
    double g;
    cin>>g;
    if(g >= 92.8){
        cout<<"jin"<<endl;
    }
    else if(g >= 85.6){
        cout<<"yin"<<endl;
    }
    else if(g >= 82.1){
        cout<<"tong"<<endl;
    }
    else{
        cout<<"sorry"<<endl;
    }
    return 0;
}
  • 例子3

输入年份,判断是否为闰年。

如果是,则输出 “yes” ,否则输出 “no” 。

提示:闰年的判断有两个条件,只需满足一个即可

1.能够被4整除但不能被 100 整除的为闰年;

2.能够被 400 整除的为闰年;

int year;
cin>>year;
if((year%4 == 0&&year%100!=0)||(year%400==0)){
    cout<<"yes"<<endl;
}
else {
    cout<<"no"<<endl;
}

八:循环控制语句

1. while 循环

伪代码:

while(表达式 == true){
    执行内容;
}
int a = 10;
// while 循环执行
while( a < 20 ){
   cout << "a 的值:" << a << endl;
   a++;
}
  • 死循环
int a = 0;
while(1){
    a++;
    cout<<a<<endl;
}
2. for 循环

伪代码:

for( a; b ; c )
{
    执行内容;
}
a 初始化;
b 判断条件;
c 每执行完一次循环里的内容后,执行一次
所以执行顺序是:
a->b->执行内容->c->b->执行内容->c->b.......
for(int i = 1;i <= 10;i ++){
    cout<<i<<" ";
}
cout<<endl;
1 2 3 4 5 6 7 8 9 10
    
for(int i = 1;i <= 10;i += 2){
    cout<<i<<" ";
}
cout<<endl;
1 3 5 7 9 

可以缺省:

int i = 0;
for( ;i <= 10;i ++){
    cout<<i<<endl;
}

for(int i = 1;i <= 10; ){
    cout<<i<<endl;
}
//死循环
for(int i = 1; ;i ++){
    cout<<i<<endl;
}

for(;;;){
    
}
  • b r e a k break break 语句

如果在循环过程中,发现不满足条件了,直接跳出整个循环

for(int i = 1;i <= 10;i ++){
    cout<<i<<endl;
    if(i > 5){
        break;
    }
    cout<<"***"<<endl;
}
1 
***
2
***
3
***
4
***
5
***
6
  • c o n t i n u e continue continue 语句

循环中某一次满足了条件,不再执行该语句之后的内容,直接进入下一次循环。

for(int i = 1;i <= 10;i ++){
    cout<<i<<endl;
    if(i == 5) 
        continue;
    cout<<"***"<<endl;
}
1 
***
2
***
3
***
4
***
5
6
***
7
***
8
***
9
***
10
***

好了,我们来写一个经典 9x9乘法表

(img-MRhJR7HF-1632487174656)

for(int i = 1;i <= 9;i ++){
    for(int j = 1;j <= i;j ++){
        cout<<j<<" * "<<i<<" = "<<j*i<<"\t";
    }
    cout<<endl;
    cout<<endl;//空行
}

(img-si8DzxyF-1632487174656)

九:输入问题
1.多组输入

输入包含一系列的a和b对,通过空格隔开。一对a和b占一行。

int a,b;

//C版本
while(scanf("%d %d",&a,&b)!=EOF){
    printf("%d\n",a+b);
}
//C++版本
while(cin >> a >> b){
    cout << a + b << endl;
}
2.t组样例

第一行是一个整数t,表示后面会有t行a和b,通过空格隔开。

int t;
cin>>t;
while(t--){
    int a,b;
    cin>>a>>b;
}
//这个对于还要额外输出比较好用。
//Case #1: 
for(int i = 1;i <= t;i ++){
    int a,b;
    cin>>a>>b;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QTIXgB9p-1632487174657)(https://i.loli.net/2021/09/24/oOn81WeuEkaH65l.png)]

十:一道思维题

(img-dSTlZfkA-1632487174658)

if((a==0)&&(b==0)) cout<<0<<endl;
else if((a==b)||(a==-b)) cout<<1<<endl;
else if((abs(a-b)%2)==1) cout<<-1<<endl;
else cout<<2<<endl;
  • 6
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疯狂的码泰君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值