8.23集训笔记

数据结构

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,m,c,a[N],st[N],ans;

void sol1_70(){ // O(n*2)  TLE  time limit E
    for(int i=1; i<=n; i++){
        for(int j=1; j<=n; j++){
            if(a[i] - a[j] == c) ans ++;
        }
    }
}
void sol2_70(){ // o(n) RE  runtime error
    // st[i] 表示 i 的个数 
    for(int i=1; i<=n; i++) st[ a[i] ] ++;
    for(int i=1; i<=n; i++) {
        int b = a[i]-c;
        ans += st[ b ];
    }
}
// map<int,int> mp;  mp[x] = y;
void sol3_100(){
    map<int,int> mp;
    for(int i=1; i<=n; i++) mp[ a[i] ] ++;
    for(int i=1; i<=n; i++) {
        int b = a[i]-c;
        ans += mp[ b ];
    }
} 
void sol4_100(){
    sort(a+1, a+1+n);
    for(int i=1; i<=n; i++){
        int b = a[i] - c;
        int l = lower_bound(a+1, a+1+n, b) - a; // >= b 的第一个元素位置 
        int r = upper_bound(a+1, a+1+n, b) - a; // > b  的第一个元素位置 
//        bool f = binary_search(a+1, a+1+n, b);  // 返回 b 是否存在 
        ans += r-l; 
    }
}
int main(){
    cin>>n>>c;
    for(int i=1; i<=n; i++) cin>>a[i];
    sol4_100();
    cout<<ans;
    return 0;
}

指针

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=110;

int a = 10;
int* point_a = &a; // 指针 
double b = 123.4;
double *pb = &b;
int * pc = NULL;  // 空指针 

int main(){
    cout<<a<<endl;    // 10
    cout<<&a<<endl;   // 0x3f3f3f3f
    cout<<point_a<<endl; // 0x3f3f3f3f
    cout<<*point_a<<endl; // 0x3f3f3f3f

    cout<<b<<endl;    // 10
    cout<<&b<<endl;   // 0x3f3f3f3f
    cout<<pb<<endl;   // 0x3f3f3f3f
    cout<<*pb<<endl;   // 0x3f3f3f3f

    cout<<pc<<endl; 
    return 0;
}

单向链表

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;

struct Node{
    int data;
    Node *nxt;
}a[N];
int main(){
    a[1] = {11, NULL};
    a[2] = {12, NULL};
    a[3] = {13, NULL};
//  需求:建立链表:11 -> 13 -> 12 -> NULL; // NULL 表示 0,空,没有 
//  结构体元素使用 . 访问
//  指针元素使用  -> 访问  
    Node *pa = &a[1];  // pa 等效于 &a[1] 
    a[1].nxt = &a[3];
    a[3].nxt = &a[2];
//    a[2].nxt = &a[1]; 加上后变为循环链表 
    
    while(pa != NULL){
//        cout<<(*pa).data<<endl; // (*pa) 等效于 a[1] 
        cout<<pa->data<<endl;
        pa = pa->nxt;
    }
    return 0;
}


双向链表

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;

struct Node{
    int data;
    Node *pre, *nxt;
}a[N];
int main(){
    a[1] = {11, NULL, NULL};
    a[2] = {12, NULL, NULL};
    a[3] = {13, NULL, NULL};
//    需求:建立链表:11 - 13 - 12 - NULL; // NULL 表示 0,空,没有 
//  结构体元素使用 . 访问
//  指针元素使用  -> 访问  
    Node *pa = &a[1];  // pa 等效于 &a[1]
    Node *pb = &a[2];  // pa 等效于 &a[1]
    a[1].nxt = &a[3];
    a[3].nxt = &a[2];

    a[2].pre = &a[3];
    a[3].pre = &a[1];
    while(pa != NULL){
//        cout<<(*pa).data<<endl; // (*pa) 等效于 a[1]
        cout<<pa->data<<endl;
        pa = pa->nxt;
    }
    while(pb != NULL){
        cout<<pb->data<<endl;
        pb = pb->pre;
    }
    return 0;
}
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int q, n=1;
struct Node{
    int data;
    Node *nxt;
}a[N];
Node* find(int x){ // 返回 x 所在位置,没有就返回 NULL 
    Node* p = &a[1];
    while(p != NULL){
        if(p->data == x) break;
        p = p->nxt;
    }
    return p;
}
void insert(int x,int y){ //在 x 后插入 
    Node *p = find(x);
    a[++n] = {y, p->nxt};
    p->nxt = &a[n];
}
void erase(int x){ // 删除 x 的后节点 
    Node *p = find(x);
    if(p==NULL || p->nxt==NULL) return;
    p->nxt = p->nxt->nxt; 
}
int main(){
    freopen("data.in", "r", stdin);
    cin>>q; a[1] = {1,NULL};
    int op,x,y;
    while(q--){
        cin>>op>>x;
        if(op==1){
            cin>>y; insert(x, y);
        }else if(op==2){
            Node *p = find(x);
            if(p==NULL || p->nxt==NULL) x=0;
            else  x = p->nxt->data;
            cout<<x<<endl;
        }else if(op==3){
            erase(x);
        }
    }
    return 0;
}
  • 方式2:下标模拟链表
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int q,n=1;
struct Node{
    int data;
    int nxt;
}a[N];
int find(int x){ // 查询 x 的出现位置,没有就返回 0 
    int p = 1;
    while(p){
        if(a[p].data == x) break;
        p = a[p].nxt;
    } 
    return p;
}
void insert(int x,int y){
    int p = find(x);
    a[++n] = {y, a[p].nxt};
    a[p].nxt = n;
}
void erase(int x){ // 删除 x的后节点 
    int p = find(x);
    if(p==0) return;
    a[p].nxt = a[ a[p].nxt ].nxt;
}
int main(){
//    freopen("data.in", "r", stdin);
    scanf("%d", &q); a[1] ={1,0};
    int op,x,y;
    while(q--){
        scanf("%d%d",&op,&x);
        if(op==1){
            scanf("%d", &y); insert(x, y);
        }else if(op==2){
            int p = find(x);
            if(p==0) x = 0;
            else x = a[ a[p].nxt ].data;
            cout<<x<<endl; 
        }else if(op==3){
            erase(x);
        }
    }
    return 0;
}
  • 方式3:数组模拟链表
点击查看代码

队列

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
// 数组模拟队列 
int que[N], front=0, tail=-1; // if(front > tail) 为空
int main(){
// 1-7 入队
//    for(int i=1; i<=7; i++) que[ ++tail ] = i;
//    for(int i=front; i<=tail; i++){
//        cout<<que[i]<<" ";
//    }

    queue<int> q;  // STL 的队列
    for(int i=1; i<=7; i++) q.push(i);
//    while(!q.empty()){
    while(q.size()){
        cout<<q.front()<<" ";
        q.pop();
    }
    return 0;
}
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=110;
queue<int> q;
int n;
/*
queue<Type> q;  //定义队列,Type为数据类型,如int,float,char等
q.push(item);   //把item放进队列
q.front();      //返回队首元素,但不会删除
q.pop();        //删除队首元素
q.back();       //返回队尾元素
q.size();    //返回元素个数
q.empty();     //检查队列是否为空
*/
int main(){
    freopen("data.in", "r", stdin);
    cin>>n;   int op,x;
    while(n--){
        cin>>op;
        if(op==1){
            cin>>x; q.push(x);
        }else if(op==2){
            if(q.empty())  cout<<"ERR_CANNOT_POP"<<endl;
            else q.pop();
        }else if(op==3){
            if(q.empty()) cout<<"ERR_CANNOT_QUERY"<<endl;
            else cout<<q.front()<<endl;
        }else if(op==4){
            cout<<q.size()<<endl;
        }
    }
    return 0;
}

优先队列/堆

二叉树

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=110;
struct T{
    int lch, rch;
}tree[N];
// tree[i].lch     i 的 左儿子 
// tree[i].rch     i 的 右儿子 
void pre(int rt){ // 先序遍历 以 rt为根的子树
    if(rt==0) return; 
    cout<<rt<<" ";       // 根
    pre(tree[rt].lch);// 左 
    pre(tree[rt].rch);// 右 
}
void in(int rt){ // 中序遍历 以 rt为根的子树
    if(rt==0) return; 
    in(tree[rt].lch);// 左 
    cout<<rt<<" ";      // 根
    in(tree[rt].rch);// 右 
}
void post(int rt){ // 后序遍历 以 rt为根的子树
    if(rt==0) return; 
    post(tree[rt].lch);// 左 
    post(tree[rt].rch);// 右 
    cout<<rt<<" ";        // 根
}
int main(){
    int n,l,r; cin>>n;
    for(int i=1; i<=n; i++) {
        cin>>l>>r;
        tree[i] = {l,r};
    } 
    pre(1);  cout<<endl; 
    in(1);   cout<<endl;
    post(1);
    return 0;
}

图论前置知识:https://blog.csdn.net/smallrain6/article/details/123444632

posted @ 2023-08-23 12:05  HelloHeBin  阅读(201)  评论(0)    收藏  举报