这是一个拥有c++云课堂所有知识点的代码笔记
可以让一个不会的新手变成一个大佬的笔记
(持续更新)(持续更新)(持续更新)(重要事情说三遍)
目录
1级
第一课--头文件的调用
/*
陈袁鑫
2023.9.23
9.23做
*/
//调用头文件
#include <iostream>
using namespace std;
//代码主题
int main()
{
//数字
cout<<25<<endl;
//算式
cout<<10+130<<endl;
//程序运行时,会自动计算得数并将得数输出,所以运行结果是94
//输出字符或字符串
cout<<"A"<<endl;
cout<<"abcd"<<endl;
//当输出项为一串用双引号引起的字符(称为字符串)时,则原样输出双引号中的内容。
//两种结合
//cout可以有一个输出项,也可以有多个输出项
cout<<"A"<<" "<<"abcd"<<endl;
//每一句话都以分号结尾
return 0;
}
第二课--定义数组
/*
陈袁鑫
2023.9.23
9.23做
*/
#include <iostream>
using namespace std;
int main()
{
//数组的定义
int n;//声明一个变量
//赋值
n=10;
//可以在定义的时候赋值int n=10;
//间接复制
int m;
m=n;
//自己赋值
n=n*1;
n=n-1
....
//加与减
int x=2,y=2;
x++;//x+1
y--;//y-1
//输入
int n1;
cin>>n1;
cout<<n<<endl<<m<<endl<<<x;
return 0;
}
第三课--运算符
/*
陈袁鑫-C01L03
2023.9.24做
*/
#include <iostream>
using namespace std;
//运算符
int main()
{
//运算符有:+,-,*,/,%
int n;
n=10;
n*=2;
//相当于10x2=20
int m=5;
m/=2;//int类型的只保留整数,除非用float(单精度) 或double(双精度)
//注意:每一个运算符之后都要加一个=,不然会报错
int k=10;
k+=10;
//与正常加法一样
int n1=6;
n1-=1;
//与正常减法一样
int a=10;
a%=10;
//代表a除10的余数
cout<<"n*2的值是:"<<" "<<n<<endl;
cout<<"m/2的值是:"<<" "<<m<<endl;
cout<<"k+10的值是:"<<" "<<k<<endl;
cout<<"n1-1的值是:"<<" "<<n1<<endl;
cout<<"a%2的值是:"<<" "<<a<<endl;
return 0;
}
第四课--bool变量
/*
陈袁鑫-C01L04
2023.9.24做
*/
#include <iostream>
using namespace std;
//关系表达式
int main()
{
if(2==3){
//==相当于等于
//2不等于3
cout<<"true";
//true表示✔
}
else{
cout<<"false";
//false表示❌
}
//上列代码表示判断2等不等于3
//if是如果,else是否则
/*
if(变量1==或>或<或>=或变量2){
是的条件
}
else{
否则的条件
}
*/
bool f;
//bool 布尔类型变量
//布尔型的数据用来表示某个事情有且只有两种可能的结果: true 和 false 。
//一般用 true 表示肯定意义的结果,也就是真的、成立的;
//用 false 表示某种否定意义上的结果,也就是假的、不成立的。
//&&表示并且
//||表示或者
return 0;
}
第五课--if语句
/*
陈袁鑫
2024.9.25
第五课嵌套if
*/
#include <iostream>
using namespace std;
int main()
{
int n;
n=10;
//if语句格式:
/*
if(变量1>或==或<或>=或<=){
如果是的条件
}
else{
如果不是的条件
}
*/
//比如
if(n>2){
cout<<"是";
}
else{
cout<<"不是";
}
//还可以嵌套
if(n>=10){
if(n>2){
cout<<"是";
}
else{
cout<<"不是";
}
}
//切记,只有if才有else,否则会报错
return 0;
}
第六课--复合语句
/*
陈袁鑫
2024.9.25
第六课复合语句
*/
#include <iostream>
using namespace std;
int main()
{
//我们来看下面的代码
int n=10,a=0,b=0,c=0;
if(n>0)
a+=2;
b+=2
c+=2;
cout<<a<<" "<<b<<" "<<c<<endl;
//运行上列代码,就会发现,当if语句后面有多个语句的时候
//if语句识别不到后面的语句
//这时,就要用一个大括号{},将代码包在里面,就可以运行多个语句了
int m=10,d=0,e=0,f=0;
if(m>0){
d+=2;
e+=2;
f+=2;
}
cout<<d<<" "<<e<<" "<<f;
return 0;
}
第七课--for语句
/*
陈袁鑫
2024.9.25
第七课for语句
*/
#include <iostream>
using namespace std;
int main()
{
//如果要一下子输出多个代码的话,普通人只会用cout输出
//但有些人却会用for循环来写
//如下
for(int i=1;i<=1000;i++){
cout<<"YES";
}
cout<<"________________________";
//for循环可以将括号里的代码执行上面小括号里填的数的次数
/*
for(变量类型,变量名=开始值;变量名<=结束值;变量名+=累加的次数){
代码
}
*/
//还可以
for(float i=0.5;i<=8.5;i+=0.5){
cout<<"YES";
}
return 0;
}
第八课--累加器
/*
陈袁鑫
2024.9.25
第八课累加器
*/
#include <iostream>
using namespace std;
int main()
{
//如果你要求出1+到1000是多少
//那就不得不用累加器了
//代码如下
int s=0;
for(int i=1;i<=1000;i++){
s+=i;
}
cout<<"s的值是:"<<s<<"_____________";
//正如你所见,累加器只是拿一个变量来加,+号在前面讲过
//相当于一个数来加一个,累加器必须要搭配for来用,要么就加100甚至上千次
//s的类型是什么,它加的数就是什么,比如s的类型是double,它就要+小数
return 0;
}
第九课--查找最值
/*
陈袁鑫
2024.9.25
第九课 查找最值
*/
#include <iostream>
using namespace std;
int main()
{
//如果题目要你找出最值的话,你会怎么办呢
//有些人可能会用排序来写,但是,要求位置的话呢
//这就不得不使用最值方法
//最值只是一个变量而已,但是,他为什么可以做到查找最值呢
//我们来看代码
int ma=0;//最初赋值,可以用INT_MIN,因为你一开始不用最小,之后该怎么求最值呢
int a[9]={0,1,4,2,3,5,7,6,8};//准备求最大值的数组
for(int i=1;i<=n;i++){
if(ma<a[i]){//最大值判断
ma=a[i];
}
}
cout<<"在a数组中的最大值是:"<<ma<<endl;
int mi=INT_MAX;//同上
for(int i=1;i<=9;i++){
if(mi>a[i]){//最小值判断
mi=a[i];
}
}
cout<<"在a数组中的最小值是:"<<mi<<endl;
return 0;
}
第十课--嵌套循环
/*
陈袁鑫
2024.9.26
嵌套循环
*/
#include <iostream>
using namespace std;
int main()
{
//嵌套循环一般用于输出图形而被使用,下面的是它的格式
//双重循环格式:
/*
for(循环条件1){
语句1;
for(循环条件2){
语句2;
}
}
*/
//这样可以输出一个二维图形
//因为i负责行,j负责列
//请看下列代码
for(int i=1;i<=8;i++){
for(int j=1;j<=8;j++){
cout<<"*";
}
cout<<endl;
}
/*
这样可以输出一个方阵
就是当i与j的循环次数相等
之后还可以改一下里面的数据
*/
//有双重循环就有多重循环
/*
for(循环条件1){
语句1;
for(循环条件2){
语句2;
for(循环条件3){
语句3;
}
}
}
*/
//这样子就可以输出更复杂的图形了
return 0;
}
第十一课--数位分离
/*
陈袁鑫
2024.9.26
while循环
*/
#include <iostream>
using namespace std;
int main()
{
//听说过可以统计数字的循环,但你见过
//专门应对数位分离的循环吗❓
//这个循环就是while循环
/*
while(怎样才运行){
代码;
}
*/
/*
for循环一般应用于循环次数已知的情况;
while循环一般应用于循环次数未知的情况;
在一般情况下,这两者是可以相互转化的。
举一个简单较适合用for循环的例子:
求1-100的和。
*/
/*
#include<bits/stdc++.h>
using namespace std;
int main()
{
int sum=0;
for(int i=1;i<=100;i++)
sum += i;
cout<<sum;
return 0;
}
*/
/*
接下来再举一个适用于while循环的例子:
求输入的一个整数各位数字之和。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,sum=0;
cin>>n;
while(n!=0)
{
sum += n%10;
n /= 10;
}
cout<<sum;
return 0;
}
*/
return 0;
}
2级
第一课--定义数组
/*
陈袁鑫
2024.9.25
二级第一课 一维数组的定义
*/
#include <iostream>
using namespace std;
int main()
{
//数组名代表的不是一个变量,而是一批变量
//因此不能直接读入整个数组,而是要逐个读入数组元素,通常用循环语句来完成这一功能。
int a[110];
//变量类型 变量名[数据范围];
for(int i=1;i<=10;i++){
cin>>a[i];
}
//也可以单独输入
cin>>a[11];
//数组元素的输出通常用循环语句来实现。
for(int i=1;i<=10;i++){
cout<<a[i]<<" ";
}
//当然,也可以单独输出
cout<<a[11];
//一维数组的赋值通常是利用循环语句来实现。
int b[11];
b[1]=0;
//也可以用循环赋值
for(int i=1;i<=10;i++){
b[i]=i;
cout<<b[i]<<endl;
}
//数组下标用于标明某一元素在数组中的位置,它与数组元素一一对应。
//在某个数组中查找满足某个特定条件的数据,可以从数组的第一个至最后一个逐个进行比较。
return 0;
}
第二课--最大最小值查找
/*
陈袁鑫
2024.9.26
最大最小值
*/
#include <iostream>
using namespace std;
int main()
{
/*
假设一个最大值 maxx=0 ;
maxx 依次跟数组中的元素进行比较;
如果该数组元素大于 maxx ,则将该数组元素值赋值给 maxx ;
maxx 即为该数组中的最大值。
参考代码
#include<bits/stdc++.h>
using namespace std;
int n,x[101];
int maxx=0;//maxx初始值要比任一数组元素的值小
int main()
{
cin>>n; //读入数组元素个数
for(int i=1;i<=n;i++) //数组赋值
cin>>x[i];
for(int i=1;i<=n;i++) //数组元素依序跟maxx比较
if(x[i]>maxx) maxx=x[i];
cout<<maxx; //将最大值输出
return 0;
}
*/
/*
假设一个最大值 maxx=0,并定义一个变量 pos 记录最大值下标;
maxx依次跟数组中的元素进行比较;
如果该数组元素大于 maxx,则将该数组元素值赋值给 maxx ,同时将该元素的下标值赋值给 pos ;
pos 即为该数组中的最大值的下标。
#include<bits/stdc++.h>
using namespace std;
int n,a[105];
int maxx=0,pos;//maxx初始值要比任一数组元素的值小
int main()
{
cin>>n; //读入数组元素个数
for(int i=1;i<=n;i++) //数组赋值
cin>>a[i];
for(int i=1;i<=n;i++) //数组元素依序跟maxx比较
if(a[i]>maxx) maxx=a[i],pos=i; //记录最大值跟最大值的下标
cout<<pos; //将最大值下标输出
return 0;
}
*/
return 0;
}
第三课--数组元素的移动、插入、删除
/*
陈袁鑫
2024.9.26
数组元素的移动、插入、删除
*/
#include <iostream>
using namespace std;
int main()
{
/*
明明帮助老师按学号顺序把 402 班的数学成绩输入到电脑,完成输完后发现 18 号同学的成绩忘记输入。
使得后面所有同学的成绩都错位了。能不能设计一个程序把这个同学的成绩插入到正确的位置,使得成绩和学号一一对应?
解题思路
从插入位置起所有后面的同学都要向后退一步,先把那个位置空出来,然后就可以插入一个新成员。
元素的移动:数组元素位置发生变化。
例如,将数组中位置2的元素移动到位置1,可以写成:
a[1]=a[2]; //注意此时原位置1的被覆盖。
又如,将a数组中第一个元素移动到数组末尾,其余数据依次往前平移一个位置,可以按如下步骤实现:
把第一个元素的值取出放在一个临时单元temp中。
通过 a[1]=a[2];a[2]=a[3];a[3]=a[4]; ... a[n-1]=a[n] ,实现其余元素前移。
将 temp 值赋给 a[n]。
可以用以下语句实现:
temp=a[1]; //用temp暂存a[1]
for (int i=1;i<=n-1;i++) //2到n位数据前移
a[i]=a[i+1];
a[n]=temp; //把temp存到数据末尾
*/
/*
元素的删除:删除数组中某个特定位置的元素。a[5] 的数据虽然仍然存在,但是删除元素之前 n = 5。
删除后 n = 4,所以 a[5] 的值已经不在被关注,这个值留在数组内并不影响后续的计算了。
可以用以下语句实现:
for (int i=3;i<=4;i++)
a[i]=a[i+1];
因此,可以用以下程序解决明明的问题:
#include<iostream>
using namespace std;
int a[1001];
int main()
{
int n,m;
cin>>n;
for (int i=1;i<=n;i++)
cin>>a[i];
for (int i=n;i>=18;i--)
a[i+1]=a[i]
cin>>m;
a[18]=m;
for (int i=1;i<=n+1;i++)
cout<<a[i]<<" ";
return 0;
}
*/
return 0;
}
第四课--选择排序
/*
陈袁鑫
2024.9.26
选择排序
*/
#include <iostream>
using namespace std;
int main()
{
/*
今天,数学老师找到了明明,让他把 1000 个学生的数学成绩按从高分到低分输入电脑。
就像我们排队是从高到矮一样,将同一类型的数据按一定顺序(从大到小或从小到大)排列称为排序。排序的算法有很多,其中选择排序是一种较简单的方法。
例如:输入 5 个正整数,把这 5 个数按由大到小的顺序排列。
分析:要把5个数按从大到小顺序排列,则排完后,第一个数最大,第二个数次大,...... 。因此,我们第一步可将第一个位置的数与其后的各个数依次比较。
若发现有数比它大的,则互相交换位置,这样结束后,第一个位置的数就是最大的数。
用1号数据和后面2到5号的数据依次比较,确定 “第一大” 的数据。
-----
| |
20 10 50 40 10
第一次是 1 号和 2 号比较,20 > 10,所以数据不变。
-------
| |
50 10 20 40 10
第二次是 1 号和 3 号比较,20 < 50,所以交换数据。
-----------
| |
50 10 20 40 10
第三次是 1 号和 4 号比较,50 > 40,所以数据不变。
.....
经过多轮比较,最后确定的顺序是:
10 10 20 40 50
这种排序方法叫选择排序:(从大到小)
for (int i=1;i<=n-1;i++) //确定第i个位置的数据
for(int j=i+1;j<=n;j++) //将第i个数与其后所有数比较
if (a[i]<a[j]) //若a[j]比a[i]大,则交换数据
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
*/
return 0;
}
第五课-sort函数
/*
陈袁鑫
2024.9.26
sort函数
*/
#include <iostream>
using namespace std;
int main()
{
/*
sort函数包含在头文件为 algorithm 的c++标准库中
这里建议用万能头文件:
#include<bits/stdc++.h>
sort函数有三个参数:
第一个是要排序的数组的起始。
第二个是结束的
第三个参数是排序的方法,可以是从大到小也可是从小到大,还可以不写第三个参数,此时默认的排序方法是从小到大排序。
sort函数使用模板:
sort(start,end,排序方法);
排序方法可以不填,这时候用的是该数组数据类型的默认排序方法。
下面就具体使用 sort( ) 函数结合对数组里的十个数进行排序做一个说明:
例一:输入10个整数,从小到大输出。
{
int a[10]={9,6,3,8,5,2,7,4,1,0};
for(int i=0;i<10;i++)
cout<<a[i]<<" ";
cout<<endl;
sort(a,a+10);
for(int i=0;i<10;i++)
cout<<a[i]<<" ";
cout<<endl;
下面是运行结果
输入
9 6 3 8 5 2 7 4 1 0
0 1 2 3 4 5 6 7 8 9
*/
return 0;
}
第六课--输入输出函数
/*
陈袁鑫
输出输入函数
*/
#include<bits/stdc++.h>
using namespace std;
//unsigned long long ;
int main(){
//我们学习过的 cin、cout,一般情况下,用来输入、输出数据已经足够了。
//但这种方法电脑的运行效率比较低,尤其是数据量达到 10 万个以上时会超时。
//为了能够更快输入、输出较多的数据,需要使用格式化输入(scanf)和输出函数(printf)。
//格式是
// scanf(格式控制符,变量名);
// printf(格式控制符,变量名);
//例如:scanf("%d",&a);printf("%d",a);它们也有着和cin与cout一样的好处
//同时也可以输出文字
//scanf("%d",a+1); // a+1 是数组元素的第二个元素的地址,所以写 a+1 相当于写 &a[1];
// 漏了写&,会出现 runtime 错误
//long long a;
//scanf("%d",&a);
//变量是 long long 类型,但是 scanf 的第一个参数格式说明说的是 int 类型。
return 0;
}
第七课--模拟算法
/*
陈袁鑫
2024.9.30
模拟算法
*/
#include <iostream>
using namespace std;
int main()
{
//所谓模拟法,就是用计算机模拟某个过程,通过改变数学模型的各种参数,进而观察变更这些参数所引起的过程状态的变化,然后从中得出解答。
//模拟题的算法一般都不太复杂,关键是所有条件都不能遗漏并要把条件分析清楚。
//竞赛题目中一般都会给出输入输出样例,以便检查程序的输入输出格式是否正确
//但这些样例往往会比竞赛时评判所用的测试数据简单,所以你不能满足于通过这些样例。
//还要尽量自拟一些更复杂、更全面的测试数据来检查程序的正确性
//比如下面这道题
/*
小明每天都可以从妈妈那里领到零花钱,第 1 天可以领到 1 块钱,第2天可以领到 2 块钱......,第 i 天可以领到 i 块钱。
//如果小明领到零花钱后,手上的零花钱是 3 的倍数时。
//小明就会将他手上所有零花钱的三分之一存在妈妈那里(假设小明的零花钱从来不花!)。
//K 天的时候小明手上有多少零花钱呢?
*/
//是下面的代码
/*
int k,s;
cin>>k;
for(int i=1;i<=k;i++)
{
s=s+i; //第 i 天的零花钱为i元
if(s%3==0) s=s/3*2; //如果手上的零花钱s为3的倍数,存三分之一在妈妈那,自己留三分之二。
}
cout<<s;
*/
//算法就是运用前面学的知识合并到一起来运用的
return 0;
}
第八课--周期问题
/*
陈袁鑫
2024.9.30
周期问题.算法知识
*/
#include <iostream>
using namespace std;
int main()
{
//在我们的生活中,有很多按照一定规律反复出现、周而复始不断循环的自然现象或客观事件。
//比如一年中春夏秋冬四季轮回、一周中星期一到星期日7天循环、一天中24个小时不停轮转……像这种带有周期性规律出现的现象。
//我们统称为周期现象。
//在数学及信息学中,我们将带有周期性规律的问题,统称为 周期问题 。
//例如:
/*
有一列数,按 5、6、2、4、5、6、2、4、... 排列,第 n 个是几?前 n 个数的和是多少 ?( n <= 10000 )
int n;
cin>>n;
int a = n/4; //计算有多少个完整的周期
int b = n%4; //最后不够一个完整周期的数字有多少个
cout<< x[b] <<endl;
cout<<a*17 + s[b];
*/
return 0;
}
第九课--简单递推
/*
陈袁鑫
2024.9.30
简单递推.递推算法概述
*/
#include <iostream>
using namespace std;
int main()
{
//递推”是计算机解题的一种常用法。利用“递推法”解题首先要分析归纳出“递推关系”。
//如经典的斐波那契数列问题,用 f(i) 表示第 i 项的值,则 f(1) = 0 ,f(2) = 。
//在 n>2 时,存在递推关系:f(n) = f(n-1) + f(n-2) 。递推”是计算机解题的一种常用法。
//利用“递推法”解题首先要分析归纳出“递推关系”。如经典的斐波那契数列问题,用 f(i) 表示第 i 项的值。
//则 f(1) = 0 ,f(2) = 1,在 n>2 时,存在递推关系:f(n) = f(n-1) + f(n-2) 。递推”是计算机解题的一种常用法。利用“递推法”解题首先要分析归纳出“递推关系”。如经典的斐波那契数列问题。
//用 f(i) 表示第 i 项的值,则 f(1) = 0 ,f(2) = 1,在 n>2 时,存在递推关系:f(n) = f(n-1) + f(n-2) 。
//顺推和倒推
//顺推,就是从问题的边界条件(初始状态)出发,通过递推关系式依次从前往后递推出问题的解;
//倒推,就是在不知道问题的边界条件(初始状态)下,从问题的最终解(目标状态或某个中间状态)出发,反过来推导问题的初始状态。
// 解决递推问题有三个重点:
//建立正确的递推关系式;
//分析递推关系式的性质;
//根据递推关系式编程求解。
return 0;
}
第十课--简单枚举
/*
陈袁鑫
2024.9.30
简单的枚举.课堂练习1.鸡兔同笼
*/
#include <iostream>
using namespace std;
int main()
{
//枚举的意思就是把所有情况都看一遍
//把所有可能的情况输出一遍
//例如:
/*
鸡兔同笼
鸡兔同笼问题:一个笼子里面有鸡若干只,兔若干只。共有头 50 个,共有腿 160 条。求鸡兔各多少只?
正确答案是20 30
这就是要用双重循环一个一个比较出来的
有时候枚举需要优化一下
不然会超时
实际上枚举最难点在于你要最少循环多少次,才会对,且不超时
有时要n/2,n/2,n*i+1......
所以枚举是相对比较难的
*/
return 0;
}
第十一课--下计计数
/*
陈袁鑫
2023.9.23
10.10做
下标计数
*/
#include <bits/stdc++.h>
using namespace std;
int main()
{
/*
题目描述
奥林匹克运动是人类社会的一个罕见的杰作,它将体育运动的多种功能发挥得淋漓尽致,影响力远远超出了体育的范畴,在当代世界的政治、经济、哲学、文化、艺术和新闻媒介等诸多方面产生了一系列不容忽视的影响。奥林匹克运动有一句著名的格言:“更快、更高、更强(Citius, Altius, Fortius)”。
迄今为止已经奥运会(夏季)已经举办了 32 届了,在以往的这些盛会中,出现了众多耀眼的体育明星,有人说喜欢菲尔普斯、有人说喜欢博尔特,也有人说喜欢苏炳添...
现在给每个运动员都编上号,然后大家给自己最喜欢的运动员投票,最后通过将得票最多的推选为最受欢迎的奥运之星。
因为全球人数太多了,候选人也非常多,通过人力来统计非常麻烦,请你编写程序帮助将奥运之星统计出来,你能做到吗?
输入格式
第一行只有一个数:N ( 1 ≤ N ≤ 500000 ),表示参加投票的人数。
第二行有 N 个正整数,相邻数用空格隔开,所有数均不超过 100000 ,表示这 n 个人的投票情况。
输出格式
得票最多的那个数,如果有相同得票的,则输出数值较小的那个数。
*/
//上面是一道例题
//它让我们统计所有人的票数
//下面是它的正确代码:
long long n,a[500010],t,ma=INT_MIN,l;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>t;
a[t]++;//下标计数,统计次数
}
for(int i=1;i<=500000;i++){
if(a[i]>ma){//因为不确定在那,所以全部都便利一遍
ma=a[i];
l=i;
}
}
cout<<l;
return 0;
}
return 0;
}
第十二课--求连续相同的一段数
/*
陈袁鑫
2023.9.23
10.10做
求连续相同的一段数
*/
#include <bits/stdc++.h>
using namespace std;
int main()
{
/*
题目描述
FJ 的农场举行了异一场 USA 奶牛奥林匹克竞赛。N ( 1 <= N <= 100,000 ; N 是一个奇数 ) 只奶牛都已经获得了一个整数分数 S ( 0 <= S <= 10,000 )。
FJ 必须统计这些分数以便指导他们。帮帮他吧~~给出一个列表,计算最小值、最大值、中间数、众数。中间值是一个值 M ,至少一半的数 <= M ,至少一半的数 >= M 。众数是指出现次数最多的一个数。FJ 知道分数里面只有一个众数。
输入格式
第 1 行:一个整数 N 。
第 2 ~ N+1 行:每一行有一个整数,是一只奶牛的分数。
输出格式
四个用空格隔开的整数:最小值、最大值、中间数、众数。
*/
//上面是一道例题
//它让我们统计所有人的票数
//下面是它的正确代码:
long long n,a[500010];
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int ma=-1,mi=1000000010,cnt=1,cnt1,ans=0;
for(int i=1;i<=n;i++){
if(a[i]>=ma) ma=a[i];
if(a[i]<=mi) mi=a[i];
if(i>1){
if(a[i]==a[i-1]) cnt++;
}
else {
if(cnt>=cnt1)cnt1=cnt,ans=a[i];
cnt=1;
}
}
cout<<mi<<" "<<ma<<" ";
if(n%2==0) cout<<a[n/2+1]<<" ";
else cout<<(a[n/2]+a[n/2+1])/2<<" ";
cout<<ans<<" ";
return 0;
}
3级
第一课--回文数
#include <bits/stdc++.h>
using namespace std;
//unsigned long long ;
void t(string ss){
cout<<"——————————————————"<<ss<<"——————————————————"<<endl;
}
void hws(){
t("判断回文数");
int n,m;
cin>>n>>m;
int s=0,s1=0;
while(n!=0){
s=s*10+n%10;
n/=10;
}
while(m!=0){
s1=s1*10+m%10;
m/=10;
}
if(s==n) cout<<"n是回文数"<<endl;
else cout<<"n不是回文数"<<endl;
if(s1==m) cout<<"m是回文数"<<endl;
else cout<<"m不是回文数"<<endl;
}
void hwspdyzxs(){
t("回文数的一种组成形式");
int n;
cin>>n;
int s=0;
while(n!=0){
s=s*10+n%10;
n/=10;
}
if(s==n){
cout<<"当n是回文数时,他加上他的倒叙数,也是一个回文数,他是:"<<s+n<<endl;;
}
else cout<<"n不是回文数"<<endl;
}
int main(){
hws();
hwspdyzxs();
return 0;
}
第六课--字符串的定义,输出,输入与运用
/*
陈袁鑫
2024.9.30
字符串的定义,输出,输入与运用等等等等;
*/
#include <bits/stdc++.h>
using namespace std;
void t(string ss){
cout<<"----------"<<ss<<"----------"<<endl;
}
void dingyiyufuzhi(){
t("先定义");
char c='a';
char c1='b';
cout<<"字符c的值是:"<<c<<endl;
cout<<"字符c1的值是:"<<c1<<endl;
char c3[101]={'0','a','\0'};//字符数组也是和数组是一样的,赋值也和它一样
//后面记得要加\0,不然他会一直输出上一个(只会输出一次)
cout<<"c3数组里存的值是:"<<c3[0]<<" "<<c3[1]<<endl;
}
void shuru(){
t("输入");
char a1,a2,a3;
cin>>a1;
scanf("%c",&a2);
a3=getchar();//这里也可以表示输入,上一个是换行符
//注意 字符有着独特的scanf输入
//他们代表的输入是%c
cout<<"字符a1里输入的数是:"<<a1<<endl;
cout<<"字符a2里输入的数是:"<<a2<<endl;
cout<<"字符a3里输入的数是:"<<a3<<endl;
}
void shuchu(){
t("输出");
char b1,b2;
//字符的输出可以是cout
//也可以用2级内容:printf
b1='#';
b2='@';
cout<<"b1里赋值的字符是:"<<b1<<endl;
printf("b2里赋值的字符是:%c\n",b2);
}
void yushuzuzhijiandeguanzi(){
t("与数字之间的关系");
//每一个字符都有一个对应的ASCLL码值
//比如:
char c=97;
cout<<"c字符对应的字符是:"<<c<<endl;
char b=c+1;
cout<<"b字符对应的字符是:"<<b<<endl;
}
int main()
{
dingyiyufuzhi();
shuru();
shuchu();
yushuzuzhijiandeguanzi();
return 0;
}
4级
第九课--的语法知识
/*
陈袁鑫
2024.12.24
函数的语法知识
*/
#include <bits/stdc++.h>
using namespace std;
void tt(string ss){
cout<<"————————————————"<<ss<<"——————————————————"<<endl;
}
int ans(int s){
unsigned long long ans=1;
for(int i=1;i<=10;i++){
ans*=i;
}
return ans;
}
void hsdy(){
tt("函数的定义");
cout<<"我们曾经学习了程序设计中的三种基本控制结构(顺序、分支、循环)。"<<endl;
cout<<"用它们可以组成任何程序。"<<endl;
cout<<"但在应用中,还经常用到子程序结构。"<<endl;
cout<<"通常,在程序设计中,我们会发现一些程序段在程序的不同地方反复出现。"<<endl;
cout<<"此时可以将这些程序段作为相对独立的整体,用一个标识符给它起一个名字。"<<endl;
cout<<"凡是程序中出现该程序段的地方,只要简单地写上其标识符即可。这样的程序段,我们称之为子程序。"<<endl;
cout<<"子程序的使用不仅缩短了程序,节省了内存空间及减少了程序的编译时间,而且有利于结构化程序设计。"<<endl;
cout<<"因为一个复杂的问题总可将其分解成若干个子问题来解决。"<<endl;
cout<<"如果子问题依然很复杂,还可以将它继续分解,直到每个子问题都是一个具有独立任务的模块。"<<endl;
cout<<"这样编制的程序结构清晰,逻辑关系明确,无论是编写、阅读、调试还是修改,都会带来极大的好处。"<<endl;
cout<<"在一个程序中可以只有主程序而没有子程序(本章以前都是如此),但不能没有主程序,也就是说不能单独执行子程序。"<<endl;
cout<<"在此之前,我们曾经介绍并使用了C++提供的各种标准函数,如abs(),sqrt()等等"<<endl;
cout<<"这些系统提供的函数为我们编写程序提供了很大的方便。"<<endl;
cout<<"比如:求sin(1)+ sin(2)+...+sin(100)的值。但这些函数只是常用的基本函数,编程时经常需要自定义一些函数。"<<endl;
cout<<"例6.1 求:1!+2!+3!+……+10!"<<endl;
cout<<"意思是输出10的阶乘"<<endl;
cout<<ans(10)<<endl;
}
int main()
{
hsdy();
return 0;
}
第十课--结构体
在实际问题中,一组数据往往具有不同的数据类型。例如,人口大普查时,我们需要记录每一位公民的姓名,年龄,性别,住址,身份证号码。这些信息分别要用整型,字符型,字符串型来记录。为了解决问题,C++语言给出了另一种构造数据类型——“结构体”,它在数据存储方面相当于其他高级语言中的记录,但它有着面向对象的优势。
一、结构体定义和操作
1. 定义结构体及结构体变量
结构体变量的定义有两种方式:
定义结构体的同时定义结构体变量
struct 结构体名 { //其中 struct 是关键字
成员表 //可以有多个成员
成员函数 //可以有多个成员函数,也可以没有
} 结构体变量表; //可以同时定义多个结构体变量
Copy
结构体变量名列表的各个变量用“,”隔开。例如:
struct DATA{
int a[2]; //成员为一个数组
int c;
}data_a,data_b;
Copy
当然,我们也可以先定义结构体再定义结构体变量
struct 结构体名{
成员表
成员函数
};
结构体名 结构体变量表;//同样可以同时定义多个结构体变量
Copy
例如:
struct DATA{
int a[2];
int c;
};
DATA data_a,data_b;//这种定义方式与上一种方式的效果是相同的
Copy
在定义结构体变量时注意,结构体变量名和结构体名不能相同。在定义结构体时,系统对之不分配实际内存。只有定义结构体变量时,系统才为其分配内存。
2.成员调用
结构体变量与各个成员之间引用的一般形式为:
结构体变量名. 成员名
对于上面定义的结构体变量,我们可以这样操作:
cin>>data_a.a[0]>>data_a.a[1]; //一般情况下不能写 cin>>data_a;
int a=data_a.a[0]+data_a.a[1]; //就像用整形变量一样用a[0]、a[1]
data_b=data_a; //结构体之间的相互赋值是合法的
data_a.c=0; //就如同给整形变量赋值
Copy
实际上结构体成员的操作与该成员类型所具有的操作是一致的。
成员运算符“.”在存取成员数值时使用,其优先级最高,并具有左结合性。在处理包含结构体的结构体时,可记作:
strua. strub. membb
Copy
这说明结构体变量 strua 有结构体成员 strub;结构体变量 strub 有成员 membb。
3.成员函数调用
结构体成员函数调用的一般形式为:
结构体变量名. 成员函数
Copy
结构体成员函数默认将结构体变量作为引用参数。
二、结构体操作实例
现在,我们先定义一个简单的结构体,这个结构体将用来记录一个学生的大致情况,所以它的成员应该有学号、姓名、性别、年龄、成绩、家庭住址等。
#include<iostream>
using namespace std;
struct student{
int num; //学号
char name[21]; //姓名
char sex; //性别
int age; //年龄
float score; //成绩
char address[51]; //家庭住址
}; //此处不可忽略分号
struct student a,b;
int main()
{
cin>>a.num>>a.name>>a.sex>>a.age>>a.score>>a.address;
cin>>b.num>>b.name>>b.sex>>b.age>>b.score>>b.address;
cout<<a.num<<' '<<a.name<<' '<<a.sex<<' '<<a.age<<' '<<a.score<<' '<<a.address<<endl;
cout<<b.num<<' '<<b.name<<' '<<b.sex<<' '<<b.age<<' '<<b.score<<' '<<b.address<<endl;
return 0;
}
5级
第七课--字符串
/*
陈袁鑫
2024.12.25
字符串;
*/
#include <iostream>
using namespace std;
void l(){cout << endl;}
void t(string t) {cout << endl << "***** " << t << " *****" << endl;}
void ChuangJian() {
t("创建");
// 1.使用 char 变量名; 创建
char c1 = 'a', c2 = '+',
c3 = 'a' + 1,// 'b'
c4 = 99;// ASCII码为99的字符'c'
}
void ShuRu() {
t("输入");
char c2;
// 下面例子分别试输入"12345回车"和"1回车2回车3回车"查看结果
// 1.使用cin输入
cin >> c2;
cout << "3.1 c2 = " << c2 << endl;
// 2.使用 * 字符变量=getchar(); * 输入;
// !!! 可以接收回车换行符赋值给该字符(包括上一个输入结束时的回车)
c2 = getchar();// 这里过滤接收上一条输入语句“cin >> c2;”的回车换行符
c2 = getchar();// 这里可以获得想要输入的字符给c2
cout << "3.2-1 c2 = " << c2 << endl;
c2 = getchar();// 如果上一个getchar()输入时按了回车键,那么这个字符将会是换行
cout << "3.2-2 c2 = " << c2 << endl;
cout << "End" << endl;
// 3.使用scanf输入
scanf("%c", &c2);
printf("3.3 c2 = %c\n", c2);
}
void ShuChu() {
t("输出");
char c1 = 'c', c2;
// 1.使用cout输出
cout << "c1 = " << c1 << endl;
// 2.使用 *printf(\"%c\",变量名);* 输出
printf("c2 = %c\n", c2);
// 3. putchar()
char c3 = 'k';
putchar(c3);
}
void HeShuZiGuanXi() {
t("和数字之间的关系");
// 特殊记忆几个ASCII数值:'0'、'A'、'a' 的ASCII码是48、65、97
// 1.字符和整数可以互相转换,对应关系参考ASCII码表
char c6 = 97;// 在ASCII码表中97对应'a'字符
char c7 = c6 + 1;
int k7 = c7;
cout << "c7 = " << c7;
l();
cout << "k7 = " << k7;
l();
// 2. 0-9字符减去0字符可以转换成数字
char c5 = '5';
int k5 = c5 - '0';
cout << "k5 = " << k5 << endl;
// 3.通过ASCII码表输出英文字母表
for(char i='a'; i<='z'; i++) cout << i << " ";
l();
// 4.大小写字母转换
char c1 = 'd', c2 = 'A' + (c1 - 'a'),
c3 = 'E', c4 = 'a' + (c3-'A');
cout << c1 << "->" << c2 << endl << c3 << "->" << c4 << endl;
}
void ChuangJian1() {
t("创建");
// 1. 通过char 变量名[长度] 创建
char c1[20];
}
void FuZhi() {
t("赋值");
// 1. 创建时通过{}赋值
// !使用这种方式赋值时一定要多加一个'\0'字符
// ! 声明创建后不能再用{}给整个字符数组赋值
char str1[4] = {'H', 'i', '!', '\0'};
// !str1中的'\0'不计入通过strlen()获取的长度中
cout << "1. str1 = " << str1 << ",长度为" << strlen(str1) << endl;
// 2. 创建时通过字符串常量""赋值
// !说明:由于字符数组要在结束位置保存一个'\0'字符,所以指定长度要比实际的长度大1
// 错误示例:char str2[5] = "Hello";
char str2[6] = "Hello";
cout << "2. str2 = " << str2 << ",长度为" << strlen(str2) << endl;
// 3. 创建时赋值的情况可以不指定长度,此时长度默认为该字符数组常量的长度
char str3[] = "Hello";
char str4[] = {'W', 'e', '\0'};
cout << "3.1 str3 = " << str3 << ",长度为" << strlen(str3) << endl;
cout << "3.2 str4 = " << str4 << ",长度为" << strlen(str4) << endl;
// 4. 通过下标对字符数组中的某个字符赋值
char str5[] = "Hello";
cout << "4.1 str5 = " << str5 << ",长度为" << strlen(str5) << endl;
str5[1] = 'i';
cout << "4.2 str5 = " << str5 << ",长度为" << strlen(str5) << endl;
// 4. 输入赋值(见输入语法)
// !说明1. 声明创建后不能用""和{}这两种方式再对整个数组直接赋值
// str1 = {'Y', 'o', 'u'}; // !这行代码放在这里是错误的
// !说明2. 使用""赋值时字符数组会自动在结尾处加结束标志符'\0'
// 但使用{}赋值时需要手动加一个字符'\0',不然会出现预想不到的错误
// 下面例子中str41会输出为WeHello,因为str41结尾没有\0,连到了str31的地址
char str31[] = "Hello";
char str41[] = {'W', 'e'};// 此句代码有问题,漏加'\0'
cout << "说明2 str31 = " << str31 << ",长度为" << strlen(str31) << endl;
cout << "说明2 str41 = " << str41 << ",长度为" << strlen(str41) << endl;// 会输出WeHello
}
void ShuChu1() {
t("输出");
char str[6] = "Hello";
// 1. 通过 cout << 变量名; 输出
cout << "1. str = " << str << endl;
// 2. 通过 printf("%s", 变量名); 输出
printf("2. str = %s\n", str);
// 3. 通过下标输出
for(int i = 0; i < 5; i++) {
cout << str[i] << " ";
}
}
void ShuRu1() {
t("输入");
char str[5];
// 1. cin >> str
// ! 无法输入空格
cin >> str;
cout << endl << "1. str = " << str << endl;
// 2. cin.getline(数组名, 读入长度, 结束的字符(可不填,默认回车符))
// 可读入空格
getchar();// 先接收上面输入的回车符
cin.getline(str, 5);
cout << endl << "2. str = " << str << endl;
// 3. scanf("%s", 地址)。以空格或回车符作为输入的结束,字符数组名本身可以当地址
scanf("%s", str);
cout << endl << "3. str = " << str << endl;
// 4. gets(地址);。 用 gets 读入整个数组,
// 能输入空格(C++14版本后无法使用)
getchar();// 先接收上面输入的回车符
gets(str);
cout << endl << "4. str = " << str << endl;
}
void HuoQuChangDu() {
t("获取长度");
char str1[4] = {'H', 'i', '\0'},
str2[] = "abcde";
// 1. strlen() 获取字符串的实际长度(不包括结尾的空字符'\0')。
// !需要引入<cstring>库
// 2. sizeof() 返回包含'\0'在内的长度
cout << "str1长度为 " << strlen(str1) << "/" << sizeof(str1) << endl;
cout << "str2长度为 " << strlen(str2) << "/" << sizeof(str2) << endl;
}
void QiTaGongNengHanShu() {
// strcmp 比较
// strcat
// strcpy
//
}
void ChuangJian3() {
t("创建");
// 1.声明和初始化字符串
// 需要引入<string>库
string str0;
string str1 = "Hello"; // 直接赋值初始化
string str2(5, 'C'); // 使用字符和长度初始化,5个C连成的字符串"CCCCC"
string str3 = str1 + ", World!"; // 通过拼接初始化
// 字符串输入输出
cout << "1. str1: " << str1 << endl;
cout << "2. str2: " << str2 << endl;
cout << "3. str3: " << str3 << endl;
}
void PinJie() {
t("拼接");
// 1. 使用+符号拼接
string str1 = "Hello";
str1 += ",OhYeah";
cout << "1. str1: " << str1 << endl;
}
void XiuGai() {
t("修改");
string str1 = "Hello";
// 1. 通过下标访问单个字符
cout << "1. " << str1[0] << " " << str1[4] << endl;
// 2.通过下标修改单个字符
str1[0] = 'h';
cout << "2. " << str1[0] << " " << str1[4] << endl;
// 3. 重置整个字符串
str1 = "New";
cout << "3. " << str1 << endl;
}
void ChangDu() {
t("获取字符串长度");
// 1. .size()
// 2. .length()
// ! 二者是等价的
string str1 = "Hello";
cout << "1. Hello的长度: " << str1.length() << " " << str1.size() << endl;
}
void BianLiMeiGeZiFu() {
t("遍历每个字符");
// 1. 根据长度和下标访问
string str1 = "Hello";
for(size_t i=0; i<str1.size(); i++) {
cout << "1. Hello第" << i << "个字符是 " << str1[i] << endl;
}
}
void ChaZhaoZiChuan() {
t("查找子串");
// 1. .find(子串) 返回下标位置,没有找到则返回-1(string::npos)
string str1 = "Hello";
cout << "1. Hello中l的位置在" << str1.find("l") << endl;
cout << "2. Hello中He的位置在" << str1.find("He") << endl;
cout << "3. Hello中k的位置在" << str1.find("k") << endl;
cout << "4. Hello中k的位置是否是-1:" << (str1.find("k")==-1) << endl;
// str1 = "My World";
size_t found = str1.find("World");
if (found != string::npos) {
cout << "5. 使用string::npos判断:'World' found at index: " << found << endl;
} else {
cout << "5. 使用string::npos判断:'World' not found" << endl;
}
}
void BiJiaoDaXiao() {
t("比较大小");
// 1. 使用大小关系运算符比较
// 从左往右比较相应位置字符的ASCII码值,能区分大小时即返回结果
string str1 = "Hello", str2 = "Ab", str3 = "Ac", str4 = "Ac";
cout << "1. Hello>Ab:" << (str1>str2) << endl;
cout << "2. Hello<Ab:" << (str1<str2) << endl;
cout << "3. Ab>Ac:" << (str2>str3) << endl;
cout << "4. Ac==Ac:" << (str3==str4) << endl;
}
void TiQuZiChuan() {
t("提取子串");
// 1. .substr(开始位置, 长度(不写的话默认到最后))
string str1 = "Hello";
cout << "1. Hello中第2~4位置之间的字符子串:" << str1.substr(1, 3) << endl;
}
//______________________________________________________-
void ChaRuZiChuan() {
t("插入子串");
// 1. .insert(开始插入的位置,要插入的子串)
string str1 = "Hello";
str1.insert(5, " World");
cout << "1. 在Hello后面插入 World:" << str1 << endl;
}
void ShanChuZiChuan() {
t("删除子串");
// 1. .erase(开始位置, 长度)
string str1 = "Hello";
str1.erase(1, 2);
cout << "1. 删除Hello中的el:" << str1 << endl;
}
void TiHuanZiChuan() {
t("替换子串/先删除后插入");
// 1. .replace(要删除的子串的开始位置,要删除子串的长度,新插入的子串)
string str1 = "It's Your World";
str1.replace(5, 4, "Our");
cout << "1. 将Our替换Your后:" << str1 << endl;
}
void ShuChu3() {
t("输出");
// 1. 使用cout输出
string str1 = "ab c";
cout << "1. 使用cout输出" << str1 << endl;
// 2. 不能使用scanf()
// ! printf("%s", str1);是错误的
}
void ShuRu3() {
t("输入");
string str1;
// 1. 使用cin,不能获取空格
cin >> str1;
cout << "1. cin >> str1: " << str1 << endl;
// 2. 使用getline(cin, 地址),可以获取空格
getchar();// 用于获取上一个输入内容的回车键
getline(cin, str1);
cout << "2. getline(cin, str1): " << str1 << endl;
// 3. 不能使用scanf()
// ! scanf("%s", str1);是错误的
}
int main() {
ChuangJian();
ShuRu();
ShuChu();
HeShuZiGuanXi();
ChuangJian1();
FuZhi();
ShuChu1();
ShuRu1();
HuoQuChangDu();
QiTaGongNengHanShu();
ChuangJian3();
PinJie();
XiuGai();
ChangDu();
BianLiMeiGeZiFu();
ChaZhaoZiChuan();
BiJiaoDaXiao();
TiQuZiChuan();
ChaRuZiChuan();
ShanChuZiChuan();
TiHuanZiChuan();
ShuChu3();
ShuRu3();
return 0;
}
6级
第五课---尺取理论知识
尺取法是一种线性算法,也是一种高效的枚举区间的方法。
记 (l,r) 两个端点为一个序列内以 l 为起点的最短合法区间,如果 r 随 l 的增大而增大的话,我们就可以使用尺取法。
具体的做法是:
-
初始化左右端点
-
不断扩大右端点,直到满足条件
-
如果第二步中无法满足条件,则终止,否则更新结果
-
将左端点扩大1,然后回到第二步
因为 r 随 l 增大而增大,所以 r 只有 n 次变化的机会,所以时间复杂度为 O(n) 。
经典例子
给定一个长度为 n 的数列 a_1, a_2, ..., a_na1,a2,...,an 及整数 S ,求不小于 S 的连续子序列的和的最小值,假设解肯定存在。
input
n=10,S=15
a= {5,1,3,5,10,7,4,9,2,8}
尺取法示意图
首先,取得满足条件的最小序列,然后依次将响右移动,若 i 向左移动的过程中序列仍然满足条件,则不移动,否则将也向右移动。
在移动的过程中记录 j-i 的最小值。
第十一课--二维前缀和
二维前缀和,建立在一维前缀和之上,我们要求一个矩阵内一个任意的子矩阵的数的和,我们就可以用二维前缀和。
我们可以感性的将其理解为建立在二维平面上的前缀和,如下图:
红色区域所有数的和即为二维前缀和中点(i,j) 的值。
一、如何预处理
类比一维前缀和,我们可以在O(n)的时间复杂度下预处理,如下代码:
s[i] = s[i-1] + a[i];
Copy
那么对于二维前缀和,我们怎么预处理呢?
先给出算式:
Map[i][j] + Map[i-1][j] + Map[i][j-1] - Map[i-1][j-1] + a[i][j];
(a 数组是原数据数组,Map数组用于存放前缀和)
类比一维前缀和,因为我们从左到右在计算 a[i] 的时候已经知道了a[i-1] 的值,所以同理,我们从左上向右下在计算 Map[i][j] 的时候已经知道了它右上所有点的前缀和,也就是知道 Map[i-1][j]、Map[i][j-1] 和 Map[i-1][j-1] 的值,那么现在考虑为什么要做如上的运算。
其中,Map[i][j] 的初始值即为点 (i,j) 的权值,如图:
那么现在,我们要求前缀和,也就是要加上下图中橙色区域:
而我们加上的 Map[i-1][j] 即为下图蓝色区域:
加上的 Map[i][j-1] 即为下图绿色区域:
然后我们会发现,有一部分重叠了,如下图紫色区域:
而这部分就是我们要减去的 Map[i-1][j-1] 。
那么我们的预处理就完成了。
时间复杂度:O(n×m),与一维中的O(n)预处理同理。
二、如何查询
依然是类比一维前缀和,对于查询区间 (l,r) 的值,我们可以用如下代码进行 O(1) 的查询:
sum=a[r]-a[l-1];
也就是说,用右端点的前缀和值减去左端点 -1 的前缀和值即得到了区间 (l,r) 的和,如下图:
那么对于二维前缀和,我们有应该怎么办呢?
对于计算矩形(x1,y1)∼(x2,y2)的和,先给出如下算式:
sum = Map[x2][y2] - Map[x1-1][y2] - Map[x2][y1-1] + Map[x1-1][y1-1];
下面来理解算式:
现在我们要求下图中红色区域的权值和:
而我们已经预处理好了前缀和,但是我们还不直接知道矩形(x1,y1)∼(x2,y2)的权值和,那么我们考虑怎么减去那部分。
我们已经知道了 Map[x2][y2] ,而我们需要减去下图中橙色区域:
那么我们先减去 Map[x1−1][x2] ,也就是下图中蓝色区域:
然后再减去 Map[x2][y1−1] ,也就是下图中绿色区域:
然后,我们发现我们多减去了一部分,要把它加回来,而这部分就是 Map[x1−1][y1−1] ,如下图紫色部分:
这样,我们就成功的得到了需要求和的部分的值。
时间复杂度:O(1),与一维前缀和的 O(1) 同理。
7级
第六课--动态数组
/*
陈袁鑫
2023.9.23
10.14做
C07.L06.STL之动态数组.概述
*/
#include <bits/stdc++.h>
using namespace std;
void t(string ss){
cout<<"————————————————"<<ss<<"——————————————————"<<endl;
}
void dingyi(){
t("定义");
//头文件要用 #include<vector> ( 用万能头文件也可以)
vector<int> dc;
cout<<"vector<数据类型> 变量名"<<endl;
}
void shuruandshuchu(){
t("输入&输出");
vector<int> dc;
int x,y,z;
cin>>x>>y>>z;
dc.push_back(x);
dc.push_back(y);
dc.push_back(z);
cout<<"dc[0]="<<dc[0]<<endl;
}
void shuchuchangdu(){
t("输出长度&清空&判空");
vector<int> dc;
dc.push_back(1);
dc.push_back(2);
dc.push_back(3);
dc.push_back(4);
dc.push_back(5);
dc.push_back(6);
dc.push_back(7);
dc.push_back(8);
dc.push_back(9);
cout<<"dc的长度是"<<dc.size()<<endl;
dc.clear();
cout<<"dc现在是否为空"<<dc.empty()<<endl;
}
int main()
{
dingyi();
shuruandshuchu();
shuchuchangdu();
return 0;
}
第八课--二分查找&二分答案
/*
陈袁鑫
2024.12.15
C06.L06二分查找与二分答案
*/
#include <iostream>
using namespace std;
void t(string ss){
cout<<"——————————————————"<<ss<<"——————————————————————"<<endl;
}
void erfenchazhao(){
t("二分查找知识点讲解");
cout<<"二分查找只是一个算法,不是什么函数"<<endl;
cout<<"所以会相对来说简单一些"<<endl;
cout<<"先看例题:"<<endl;
cout<<"题目描述"<<endl;
cout<<"请在一个有序递增数组中(不存在相同元素),采用二分查找,找出值 x 的位置,如果 x 在数组中不存在,请输出 -1 !"<<endl;
cout<<"输入格式"<<endl;
cout<<"第一行,一个整数 n ,代表数组元素个数 ( n <= 600000 )"<<endl;
cout<<"第二行,n 个数,代表数组的 n 个递增元素 ( 1 <= 数组元素值 <= 2000000 )"<<endl;
cout<<"第三行,一个整数 x ,代表要查找的数 ( 0 <= x <= 2000000 )"<<endl;
cout<<"输出格式"<<endl;
cout<<"按题意输出位置或者 -1 。"<<endl;
cout<<"样例"<<endl;
cout<<"输入数据 1"<<endl;
cout<<"10"<<endl;
cout<<"1 3 5 7 9 11 13 15 17 19"<<endl;
cout<<"3"<<endl;
cout<<"输出数据 1"<<endl;
cout<<"2"<<endl;
cout<<"完成程序"<<endl;
/*
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
cout<<""<<endl;
*/
/*
int n,a[1000005],x;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&x);
a[n+1] = 2000001;
a[0] = -1;
int L=0, R=n+1, mid; //左右指针初始化
while(L+1<R)
{
mid = (L+R)/2;
if(a[mid]==x)
{
cout<<mid;
return 0;
}
else
{
if(a[mid] > x)
L = mid;
else
R = mid;
}
}
cout<<-1;
*/
cout<<"上面是例子,参考一下"<<endl;
}
void efda(){
t("二分答案");
cout<<"二分答案是二分的一种进阶,所以讲了没必要,有点难"<<endl;
}
int main()
{
erfenchazhao();
efda();
return 0;
}
第九课--栈的运用
/*
陈袁鑫
2023.9.23
10.10做
栈的应用
*/
#include <bits/stdc++.h>
using namespace std;
void t(string ss){
cout<<"————————————————"<<ss<<"——————————————————"<<endl;
}
void dingyi(){
t("定义");
cout<<"栈的格式:stack<数据类型>栈名"<<endl;
}
void ruzhanyuchuzhan(){
t("入栈与出栈");
stack<int>s;
int a,b;
cin>>a>>b;
s.push(a);
s.push(b);
cout<<"将栈顶元素出栈,元素是:"<<s.top()<<endl;
s.pop();
cout<<"出栈后的栈顶元素是:"<<s.top()<<endl;
}
void qingkong(){
t("清空");
stack<int>s;
s.push(5);
cout<<"输出栈是否为空:"<<s.empty()<<endl;
s.pop();
cout<<"输出栈是否为空:"<<s.empty()<<endl;
}
void fangwenchangdu(){
t("访问长度");
stack<int> s;
s.push(5);
cout<<"s的长度为:"<<s.size()<<endl;
}
void bianli(){
t("遍历");
stack<int> s;
for(int i=1;i<=5;i++){
int t;
cin>>t;
s.push(t);
}
cout<<"输出入栈的元素"<<endl;
while(!s.empty()){
cout<<s.top()<<" ";
s.pop();
}
}
int main()
{
dingyi();
ruzhanyuchuzhan();
qingkong();
fangwenchangdu();
bianli();
return 0;
}
第十课--队列
双向队列
/*
陈袁鑫
2023.9.23
10.10做
栈的应用
*/
#include <bits/stdc++.h>
using namespace std;
void t(string ss){
cout<<"————————————————"<<ss<<"——————————————————"<<endl;
}
void dingyi(){
t("定义");
cout<<"队列的格式:deque<数据类型>队列名"<<endl;
}
void ruzhanyuchuzhan(){
t("入队列与队列");
deque<int>s;
int a,b;
cin>>a>>b;
s.push_front(a);
s.push_back(b);
cout<<"将队列顶元素出队列,元素是:"<<s.front()<<endl;
s.pop_front();
cout<<"出队列后的队列顶元素是:"<<s.front()<<endl;
}
void qingkong(){
t("清空");
deque<int>s;
s.push_front(5);
cout<<"输出队列是否为空:"<<s.empty()<<endl;
s.pop_front();
cout<<"输出队列是否为空:"<<s.empty()<<endl;
}
void fangwenchangdu(){
t("访问长度");
deque<int> s;
s.push_front(5);
cout<<"s的长度为:"<<s.size()<<endl;
}
void bianli(){
t("遍历");
deque<int> s;
for(int i=1;i<=5;i++){
int t;
cin>>t;
s.push_front(t);
}
cout<<"输出入队列的元素"<<endl;
while(!s.empty()){
cout<<s.front()<<" ";
s.pop_front();
}
}
int main()
{
dingyi();
ruzhanyuchuzhan();
qingkong();
fangwenchangdu();
bianli();
return 0;
}