第六阶段知识点

dongwen 2024-10-31 19:56:57

scanf  printf
%d: 整数  %lld : 长整形   %lf  : 小数    
换行:\n  
int a;
scanf("%d",&a);
printf("%d\n",a);
字符和字符串使用cin,cout输入。



INT_MAX  整形最大值  2147483647
INT_MIN  整形最小值   -2147483648 
int c = max(a,b);   //  max函数得到a,b中最大值赋值给c
int c  = min(a,b);  //  min函数得到a,b中最小值赋值给c


//默认从小到大排序
sort(a+开始下标,a+结束下标的下一个位置);
bool cmp(Node x,Node y) {
//返回1,true 不交换
//返回0,false 交换
if(x.s<y.s) {
return true;
} else if(x.s>y.s){
return false;
}else{//起点一样 
if(x.e<=y.e) {
return true; 
}else {
return false;
}
}
}



队列特点:
(1)队列中的数据元素遵循“先进先出”(First In First Out)的原则,简称FIFO结构;
(2)有队头与队尾两个下标。
(3)在队尾添加元素,在队头删除元素。


定义 queue<类型>  名称;

1、队列的操作(函数):
(1)入队: 通常命名为void push(x)
(2)出队: 通常命名为void pop()
(3)求队列中元素个数 int size()
(4)判断队列是否为空  bool empty();
(5)获取队首元素    front() 


易错点:出队,访问队首都需要先判断是否为空,不然容易报错

遍历队列:

while(!q.empty()) {
    cout<<q.front()<<" ";
    q.pop();
}





定义栈  stack<int> s;
2、栈的常用操作为:

(1)弹栈,通常命名为pop()
(2)压栈,通常命名为push()
(3)求栈的大小,size()
(4)判断栈是否为空,  empty()
(5)获取栈顶元素的值   top()    (队列获取队首front)   (当栈为空的时候,调用top会报错)


3. 总结:出队列,出栈,访问栈顶元素,先判断是否为空 
if(!s.empty()) {
    s.pop();
}


4.链表  
首先定义结构体
struct Node{
int data;
int next;
};
习惯将下标为0的节点当做头结点。(头结点下标从来不改变)

尾插法:维护一个尾结点下标(初始的时候可以是下标0),每插入一个节点之后,更新尾下标
a[in].data = x;
a[tail].next = in;
tail = in; 
in++;


头插法:更新2个下标位置,
将头结点的next放入当前节点的next值中。然后将当前节点的下标放入头结点的next
a[in].data = x;
a[in].next = a[0].next;
a[0].next = in;  
in++;



前缀和
s[i] = s[i-1]+a[i] 
求[l,r]之间的和 : s[r]-s[l-1]


差分
将[l,r]之间都加k
b[l] =b[l]+ k;
b[r+1] = b[r+1]-k;
再对b数组求前缀和  


递归
递归:自己调用自己
递归:
         1.递归出口
         2.递归公式


宽搜模板
int d[4][2] = {{-1,0},{0,1},{1,0},{0,-1}} ;
  //第一步
(1)第一个点加入队列 
  第一个点 = true; //标记已使用 
while(!q.empty()) {//队首,队尾不在一个位置  
     (2)得到队首,出队列    
     //(3) 是否到终点 
     if(队首==终点) {
          cout<<结果;
          return 0; 
      }
      //4个方向去找是否可以走下去    
      for(int k=0;k<4;k++) {
           //(4)新的下标 
           int nexti = i+d[k][0];
           int nextj = j+d[k][1];
           //(5) 下标有效,能走,没走过 
           if(nexti>=0&&nexti<r&&nextj>=0&&nextj<c && a[nexti][nextj] =='.' && view[nexti][nextj]==0) {
                 //(6) 入队列 
                 入队列 
                 view[nexti][nextj] = true; 
           }
      } 
}


深搜模板
#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[1005][1005];
int v[1005][1005];

int d[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
void dfs(int si,int sj) {
    //2.判断是否到达终点,输出,计算
    if(si==终点.i&&sj==终点.y) {
        //输出 
    }
    //3.寻找哪些方向可以继续走下去
    for(int i=0;i<4;i++){
         int nexti = si+d[i][0];
         int nextj = sj+d[i][1];
         //下标不越界,能走,没走过
         if(nexti>=1&&nexti<=n&&nextj>=1&&nextj<=m&&a[nexti][nextj]==1&&v[nexti][nextj] ==0){
             //4.标记,统计,继续出发
             v[nexti][nextj] = 1; 
             sum++;
             dfs(nexti,nextj);  
             //有时候需要清除标记 
             v[nexti][nextj] = 0;
        } 
    } 


int main() {
    //输入 

    //1. 从起点出发,标记统计
    v[si][sj] = 1;
    sum++; 
    dfs(si,sj); 
    v[si][sj] = 0;
    return 0;



//向量  动态数组,没有长度限制  从下标0开始使用
vector<int> a;
int len = a.size() ;//得到长度
a.push_back(1);//在最后加入数字1




struct Node{
    int y;
    int w;
    //重载运算符,改成小根堆,根据权值排序 
    bool operator < (const Node &t) const{
        return t.w<w;
    }
};
priority_queue<Node> q;//定义堆