SMU Summer 2024 div2 2nd

news2024/12/29 10:22:02

文章目录

  • The Second Week
  • 一、前言
  • 二、算法
    • 1.二分图匹配/匈牙利算法
      • <1>([ZJOI2007]矩阵游戏)
      • <2>(有大家喜欢的零食吗)
    • 2.优先队列
      • <1>(Running Median)
      • <2>(旅途的终点)
    • 3. 并查集
      • <1>(食物链)
    • 4. 搜索与搜索剪枝(DFS)
      • <1>(模拟战役)
      • <2>(Linear Probing)
    • 5.搜索与搜索剪枝(BFS)
      • <1>(Jelly)
  • 三、总结


The Second Week

耐心和恒心总会得到报酬的。 ————爱因斯坦

一、前言

周二round4,打得不尴不尬吧,四题过不了,三题不够快,继续加油。
周三下午一场牛客,一开始a题一直过不了,但是好多人都过了,僵持了好久换题了,浪费了不少时间,结果回头来看又做出来了。总体感觉还可以吧,能做的都做出来了,做的也还算快,问题是后面一个半小时一题也没ac,后来补题疯狂学算法。
周五round5,打得挺糟糕的,思维不够严谨,有的点考虑不到。分辨不出题型,判断失误导致没有做出该对的题。
周六友谊赛,ac三题,用时罚时都比较长,还间接导致第四题来不及做,脑子🧠锈住了吧你。


二、算法

1.二分图匹配/匈牙利算法

二分图:
有n个点,m条线,每条线连接任意俩个点,如果可以把俩个点分别放进俩个部分,单个部分的点间没有连线,所有线段都任意连接一部分中的一个点,以及另一个部分的任意一个点,就叫作二分图。
二分图基本样式
在这里插入图片描述
二分图的最大匹配:
任意一个点最多只能连一条线就是一个匹配,最大的边数就是最大匹配。
蓝色部分与红色部分都是一个最大匹配

黄色部分是一个匹配,但并非最大,紫色部分不是一个匹配
在这里插入图片描述
增广路径:
对于一个匹配a,如果有一条交错出现在a的路径,且前后俩个端点不属于a,就把这条路径叫作增广路径。
若红色为匹配a,那么红蓝线就是这个匹配的增广路径。
在这里插入图片描述
匈牙利算法:
其实我不知道我能不能想明白…
1.从下部的一个点开始遍历,对于红线下点,找到一条未被匹配过的线段,双方匹配。得到一个最大匹配red。
2.下部第二个点,蓝线下点,进行匹配,也想跟红线上点匹配,但这是不行的,因为每个点只能匹配一个点,它就想让红线换个点。
在这里插入图片描述
3.好嘛红线下点就去找了一下,找到了另一条蓝线,于是它俩就匹配了,与此同时此时的所有线加上一条不存在的红线,就是之前匹配red的增广路径blue,且图中连上的线就是red在blue里的相反,必然会比red大。
在这里插入图片描述
4.以此类推

<1>([ZJOI2007]矩阵游戏)

题解:
t组数据,每组给出一个n*n的01矩阵,0表示白色,1表示黑色。要求通过行交换与列交换实现对角线的格子均为黑色。
不难看出行列交换难以改变黑色格子的相对位置,所以每一行每一列都必须有至少一个黑色格子。可以将行列看作是俩个集合,一一对应,如果最大路径是n则成立。
代码:

#include<bits/stdc++.h>

using namespace std;
#define int long long
int t,n;
int vis[210],h[210];
int a[210][210];
int li[210];

bool dfs(int x) {
    for (int i = 1; i <= n; i++) {
        if(!vis[i] && a[x][i]) {
            vis[i] = 1;
            //用来标记当前这一行,有多少个已经被标记的列
            //防止它在找别人时又找了回来,导致俩个行跟同一列的情况
            if(!li[i] || dfs(li[i])) {
            //如果这一列还没被标记,直接用它
            //如果已经被标记,让它去找别人
                li[i] = x;
                //记录这一列所对应的行
                return true;
            }
        }
    }
    return false;
}

signed main() {
    cin >> t;
    while (t--) {
        cin >> n;
        memset(li,0,sizeof li);
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                cin >> a[i][j];
            }
        }
        int ans = 0;
        for (int i = 1; i <= n; i++) {
        //对于每一行,寻找自己单独对应的列
            memset(vis,0,sizeof vis);
            if(dfs(i))ans++;
        }
        if(ans == n) cout << "Yes" << endl;
        else cout << "No" << endl;
    }
    return 0;
}

<2>(有大家喜欢的零食吗)

题解:
有n个小朋友和n个大礼包,保证任意一个小朋友至少会喜欢一个,求最少还需要购买多少份大礼包来保证所有小朋友都吃到自己喜欢的礼包。
二分图最大匹配板子题。
代码:

#include<bits/stdc++.h>

using namespace std;
#define int long long
int n;
int vis[510];
int a[510][510];
int lk[510];

bool dfs(int x) {
    for (int i = 1; i <= n; i++) {
        if(!vis[i] && a[x][i]){
            vis[i] = 1;
            if(!lk[i] || dfs(lk[i])) {
                lk[i] = x;
                return true;
            }
        }
    }
    return false;
}

signed main() {
    cin >> n;
    memset(a,0,sizeof a);
    memset(lk,0,sizeof lk);
    for (int i = 1; i <= n; i++) {
        int k;
        cin >> k;
        for (int j = 1; j <= k; j++) {
            int t;
            cin >> t;
            a[i][t] = 1;
        }
    }
    
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        memset(vis,0,sizeof vis);
        if(dfs(i))ans++;
    }
    if(ans == n)cout << "Yes" << endl;
    else {
        cout << "No" << endl;
        cout << n-ans << endl;
    }
    return 0;
}

2.优先队列

//升序队列,小根堆
priority_queue <int, vector<int>, greater<int>> a;
//降序队列,大根堆,默认的也是这个
priority_queue <int, vector<int>, less<int>>b;

//也可以对string排序,一些基础数据操作跟queue类似

<1>(Running Median)

这题如果能想到用优先队列,题目就很简单了。
题解:
给出t组数据,每组数据编号p,输出数据编号和中位数数量,每当输入奇数索引的数字,都要输出当前数组所对应的中位数。
用俩个优先队列储存数字,然后每次把多出来那一个输出即可,具体看注释。注意,题目对于输出格式有要求。

代码:

#include<bits/stdc++.h>

using namespace std;
#define int long long

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    //这三行不加会超时
    int t;
    cin >> t;
    for (int i = 1; i <= t ; i++) {
        int p,m;
        cin >> p >> m;
        cout << p << ' ' << (m+1)/2 << endl;
        priority_queue<int,vector<int>,greater<int>>a;
        //小根堆,后半部分数组
        priority_queue<int>b;
        //大根堆,前半部分数组
        int ls;
        cin >> ls;
        cout << ls << " ";
        b.push(ls);
        for (int j = 2; j <= m; j++) {
            cin >> ls;
            if(b.top() < ls)a.push(ls);
            //大于前半部分的数组
            else b.push(ls);
            while (a.size() > b.size() + 1) {
                b.push(a.top());
                a.pop();
            }//最多只能多一个,不然就得往另一个队列还回去
            while (b.size() > a.size() + 1) {
                a.push(b.top());
                b.pop();
            }
            if(a.size() > b.size()) cout << a.top() << ' ';
            else if(b.size() > a.size()) cout << b.top() << ' ';
            if(j % 20 == 0 && m > j)cout << endl;
        }//输出要求
        cout << endl;
    }
    return 0;
}

<2>(旅途的终点)

把这题放上来还有个原因是,我的解法好像跟正解有出入,不过我自认为我的解法还挺简便的。
题解:
有n个国家,必须按照从1到n的顺序畅游这些国家,没经过一次需要耗费ai点生命力,生命力释放完毕则回国,有k次释放神力的机会,不用耗费生命力,求最多可以畅游多少个国家。
稍微讲一下我一开始的错误思路,找到最大的k个,每遇到这些国家时用神力,生命力开始不够的时候也用神力,用完为止。可以想象如果第一个数很大,但不是第k大,耗费大量生命力,后面一连串小国家则无法更多的访问。
我的正确思路应该是对于每插入一个,进行计算需要用几次神力,生命力不够的时候当然得用神力啦,而且必须对最大的国家用神力。然后二分一下<=k次数的神力可以访问多少个国家。
答案的思路其实更为简便,一直往后找并插入到优先队列,当哪一次生命力不够的时候,开始弹出最大值,并记录使用神力的次数,当次数用完则输出当前游玩过的城市。其实从我的错误思路出发应该得走到这的。
代码:

//以下是我的代码

#include<bits/stdc++.h>

using namespace std;
#define int long long
int n,m,k;
int a[200005];
int js[200005];
priority_queue<int>c;

bool cmp(pair<int,int>x,pair<int,int>y){
    if(x.first == y.first)return x.second < y.second;
    else return x.first > y.first;
}

signed main() {
    cin >> n >> m >> k;
    int res = 0;
    int z = 0;
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        c.push(a[i]);
        res += a[i];
        while(res >= m) {
            z++;
            res-=c.top();
            c.pop();
        }
        js[i] = z;
        
    }
    
//     for (int i = 1; i <= n; i++) {
//         cout << js[i] << endl;
//     }
    
    int l = 0,r = n;
    
    while (l < r) {
        int mid = (l+r+1)/2;
        if(js[mid] <= k)l = mid;
        else r = mid-1;
    }

    cout << l;
    return 0;
}
//以下是给出的代码

#include<iostream>
#include<queue>

using namespace std;
typedef long long ll;
const int N = 2e5+5;

ll n,m,k;
ll a[N];
priority_queue<ll,vector<ll>,greater<ll>>q;

signed main() {
    cin >> n >> m >> k;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    ll sum = 0;
    for (int i = 1; i <= n; i++) {
        q.push(a[i]);
        if(q.size() > k) {
            sum+=q.top();
            q.pop();
        }
        if(sum >= m) {
            cout << i-1 << endl;
            return 0;
        }
    }
    cout << n << endl;
    return 0;
}

3. 并查集

int find(int x) {
    if(fa[x] == x)return x;
    return fa[x] = find(fa[x]);
}

void merge(int x,int y) {
    int xx = find(x),yy = find(y);
    if( xx != yy)fa[xx] = y;
}

signed main() {
    for (int i = 0; i <= n; i++) {
        fa[i] = i;
    }
return 0;
}

<1>(食物链)

食物链
题解:
a吃b,b吃c,c吃a,n个动物相应编号,现在给出k句话,有真有假,输出有几句假话。当这句话与前面冲突时,它就是假话。
每个动物其实都可以是a,b,c中的任意一个,这是一个相对关系,所以每次往里插入关系时,只要不与前面相冲突,就连接这俩个关系,否则continue。
代码:

#include<bits/stdc++.h>

using namespace std;
#define int long long
int n,k;
int fa[200005];

int find(int x) {
    return fa[x] == x? x: fa[x] = find(fa[x]);
}

void merge (int a,int b) {
    fa[find(a)] = find(b);
}

signed main() {
    cin >> n >> k;

    for (int i = 1; i <= 3*n; i++) {
        fa[i] = i;
        //fa[i]表示i是a,fa[i+n]代表i是b,fa[i+2*n]代表i是c
    }

    int cnt = 0;
    for (int i = 1; i <= k; i++) {
        int op,x,y;
        cin >> op >> x >> y;
        if( x > n || y > n){
            cnt++;
            continue;
        }
        if(op == 1) {
            if(find(x) == find(y+n) || find (x) == find(y+2*n)){
                //x是a,y是b或c
                cnt++;
            }
            else {
                merge(x,y);
                merge(x+n,y+n);
                merge(x+2*n,y+2*n);
                //这俩者等价
            }
        }
        else {
            if(find(x) == find(y) || find (x) == find(y+2*n)){
                cnt++;
            }
            else {
                merge(x,y+n);
                merge(x+n,y+2*n);
                merge(x+2*n,y);
            }
        }

    }

    cout << cnt << endl;
    return 0;
}

4. 搜索与搜索剪枝(DFS)

深度遍历就是找到最底下再返回一层找别的,以此类推
如果是需要输出此时所储存的,多开一个数组记录即可
在这里插入图片描述

void dfs(int x) {
    if(x > n){
        for (int i = 1; i <= n; i++) {
            cout << a[i] << ' ';
        }
        cout << endl;
        return ;
    }
    for (int i = 1; i <= n; i++) {
        if(vis[i])continue;
        //已经用过这个数字
        a[x] = i;
        vis[i] = 1;
        dfs(x+1);
        下一个位置
        a[x] = 0;
        vis[i] = 0;
        //状态返回
    }
}

<1>(模拟战役)

题解:
齐齐和司机在玩大炮,齐齐先手交替出手,齐齐可以准确看到对方的大炮部署,击中大炮时会在3*3爆炸,会持续波及。司机只能在齐齐出手后反击相应的大炮。
先用dfs寻找联通块,对俩者的联通块大小分别进行排序,一直用齐齐最小的联通块攻击对方最大的,最终可以保留最多的本方大炮。
代码:

#include<bits/stdc++.h>

using namespace std;
#define int long long
int m,cnt;
char a[6][102];
char b[6][102];
bool st[6][102];
int ra[500];
int rb[500];
int dx[] = {-1,0,1,-1,0,1,-1,0,1};
int dy[] = {-1,-1,-1,0,0,0,1,1,1};
int res1 = 0,res2 = 0;

void dfs(int x,int y, char c[6][102]) {
    st[x][y] = 1;
    //记录这个大炮已经被归入某一个联通块
    cnt++;
    for (int i = 0; i < 9; i++) {
        if(x+dx[i] < 0 || x+dx[i] >= 4 || y+dy[i] < 0 || y+dy[i] >= m)continue;
        if(c[x+dx[i]][y+dy[i]] == '*' && !st[x+dx[i]][y+dy[i]]) {
            dfs(x+dx[i],y+dy[i],c);
            //继续查找它是否波及到别的大炮
        }
    }
    return ;
}

void solve(){
    memset(st,0,sizeof st);
    
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < m; j++) {
            cnt = 0;
            if(a[i][j] == '*' && !st[i][j]) {
                dfs(i,j,a);
                ra[res1++] = cnt;
                //这个联通块大小
            }
        }
    }
    
    memset(st,0,sizeof st);
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < m; j++) {
            cnt = 0;
            //每次都要记得归零
            if(b[i][j] == '*' && !st[i][j]) {
                dfs(i,j,b);
                rb[res2++] = cnt;
            }
        }
    }
}

signed main() {
    cin >> m;
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < m; j++) {
            cin >> a[i][j];
        }
    }
    
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < m; j++) {
            cin >> b[i][j];
        }
    }
    
    solve();
    
    sort(ra,ra+res1,greater<int>());
    sort(rb,rb+res2);
    
    if(res1 > res2) {
        cout << -1;
        return 0;
    }
    
   int ans = 0;
    if(res1 == 0)res1 = 1;
    for (int i = res1-1; i < res2; i++) {
        ans+=rb[i];
    }//齐齐剩下的较大的联通块大小之和
    cout << ans;
    return 0;
}

<2>(Linear Probing)

非典型dfs,稍微辨析一下。
题解:
给定一个长度为n且每个数都是-1的数组a,q次询问,每个询问输入t和x,如果t=1,令h=x%n,在数组a中找到第一个为-1的数字,变成x。如果t=2,直接输出a[x%n]。
可以考虑到,在寻找第一个为-1的数字时会出现反复重复遍历同一段数组的情况,所以定义一个to数组,每次直接跳跃过去已经确定过都不是-1的数组,具体见注释。
代码:

#include<bits/stdc++.h>

using namespace std;
#define int long long 
const int N = 1048576;
int a[1050000];
int q,lq;
int to[1050000];

void dfs(int t,int x) {
    if(a[t] == -1) {
        lq = t;
        //它的下一个不为-1,标记一下
        a[t] = x;
        return ;
        //开始返回啦
    }
    dfs(to[t],x);
    to[t] = lq;
    //在回来的路上把沿途的to都直接赋值到最后一个lq
}

signed main() {
    cin >> q;
    memset(a,-1,sizeof a);
    for (int i = 0; i < N; i++) {
        to[i] = i+1;
    }to[N-1] = 0;
    while (q--) {
        int t,x;
        cin >> t >> x;
        if(t == 1) {
            int h = x;
            dfs(h%N,x);
        }
        else if(t == 2) cout << a[x%N] << endl;
    }
    return 0;
}

5.搜索与搜索剪枝(BFS)

先搜索一层再搜索下一层
由每个点向四处走,对于没走过的节点附上步数,示意图处无法走到终点
在这里插入图片描述

//一般利用队列实现
int n,m;
typedef pair<int,int> PII;
queue<PII>q;
int a[10][10];
int dis[10][10];
int dx[] = {-1,1,0,0};
int dy[] = {0,0,-1,1};

void bfs(int x,int y) {
    memset(dis,-1,sizeof dis);
    dis[x][y] = 0;
    q.push({x,y});

    while(!q.empty()) {
        PII tmp = q.front();
        for (int i = 0; i < 4; i++) {
            int lx = tmp.first+dx[i];
            int ly = tmp.second+dy[i];
            if(ly < 0 || lx < 0 || lx >= n || lx >= m) continue;
            if(dis[lx][ly] == -1) {
                dis[lx][ly] = dis[tmp.first][tmp.second]+1;
                q.push({lx,ly});
            }
        }
        q.pop();
    }
    cout << dis[n-1][m-1];
}

<1>(Jelly)

老规矩放一道板子题。
题解:
从(1,1,1)走到(n,n,n),‘*’不能走,求最短路径。
从第一个位置开始向四周没有被标记的位置扩散行走。具体见注释。
代码:

#include<bits/stdc++.h>

using namespace std;
int n;
char a[102][105][102];
int di[] = {0,0,-1,1,0,0};
int dj[] = {0,0,0,0,-1,1};
int dk[] = {-1,1,0,0,0,0};
//几个既定方向位置
int vis[105][105][105];
//标记是否走过

struct ty{
    int x;
    int y;
    int z;
};//三维数组重新定义一下。

queue<ty>q;

void bfs() {
    memset(vis,-1,sizeof vis);
    vis[1][1][1] = 1;
    //第一块果冻
    q.push({1,1,1});
    
    while(!q.empty()) {
    //全部走一遍八
        ty tmp = q.front();
        for (int i = 0; i < 6; i++) {
            int lx = tmp.x+di[i];
            int ly = tmp.y+dj[i];
            int lz = tmp.z+dk[i];
            if(lz <= 0 || lx <= 0 || ly <= 0 || lx > n || ly > n || lz > n) continue;
            if(vis[lx][ly][lz] == -1 && a[lx][ly][lz] != '*') {
                vis[lx][ly][lz] = vis[tmp.x][tmp.y][tmp.z]+1;
                q.push({lx,ly,lz});
                //来来来继续
            }
        }
        q.pop();
        //这个走完了
    }
    cout << vis[n][n][n] << endl;
    //输出即可
}

signed main() {
    cin >> n; 
    for (int i = 1 ; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            for (int k = 1; k <= n; k++) {
                cin >> a[i][j][k];
            }
        }
    }
    
    bfs();
}

三、总结

_int128是特别大的整数数据类型
signed main()必须return 0,不然会tle
map的查询和清空时间会比vector短,在多数据里考虑用map储存
nan的意思是not a number,可能是除0错误,对负数开平方等问题。
第二周总体打得飘忽不定而且没有一次比赛特别突出,算法课学起来更为吃力,搜索掌握得不太好。状态其实也没第一周好,老想划水(小小声)下周调整,继续加油。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1939171.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

运维团队如何高效监控容器化环境中的PID及其他关键指标

随着云计算和容器化技术的快速发展&#xff0c;越来越多的企业开始采用容器化技术来部署和管理应用程序。然而&#xff0c;容器化环境的复杂性和动态性给运维团队带来了前所未有的挑战。本文将从PID&#xff08;进程标识符&#xff09;监控入手&#xff0c;探讨运维团队如何高效…

下载最新版Anaconda、安装、更换源、配置虚拟环境并在vscode中使用

文章目录 进入官网进入下载页安装更换源配置虚拟环境env安装包requests在vscode中使用虚拟环境 进入官网 https://repo.anaconda.com/ 或进入清华大学下载 https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 进入下载页 安装 更换源 查看已经存在的镜像源 bash cond…

windows实现端口转发

最近在做界面开发时&#xff0c;想要直接在手机上看看实际效果&#xff0c;由于我的服务器是放在虚拟机上的&#xff0c;所以需要在window上面做个端口转发&#xff0c;这就需要用到netsh命令。 添加端口转发 netsh interface portproxy add v4tov4 listenport8080 listenadd…

广州机房搬迁网络部署方案

新机房网络部署应包括核心模块、业务模块、光传输模块、安全模块、流量采集模块、路由模块、带外管理模块等&#xff0c;每个模块都根据业务需求规划成多个POD&#xff08;Point Of Delivery&#xff0c;基本物理设计单元&#xff09;。 核心模块部署主要实现各业务模块的高速互…

语义分割——为什么单通道8bit灰度图像能显示多种色块???

目录 一、问题二、解答2.1 标签图的实际存储格式2.2 标签图的显示颜色2.3 颜色映射示例 三、应用颜色映射3.1 OpenCV显示标签图3.2 Matplotlib显示标签图 四、总结 一、问题 大家在做语义分割时不知道有没有这样的疑惑&#xff0c;使用打标签工具后&#xff0c;标签图是单通道…

大气热力学(15)——热力学图的应用之三(逆温)

文章目录 15.1 逆温的概念15.2 辐射逆温15.2.1 辐射逆温的形成原因15.2.2 辐射逆温的生消过程15.2.3 辐射逆温在探空图的特征15.2.4 辐射雾的形成与特征 15.3 平流逆温15.3.1 平流逆温的形成原因15.3.2 平流雾的形成与特征 15.4 湍流逆温15.4.1 湍流逆温的形成原因15.4.2 湍流逆…

Unity XR Interaction Toolkit(VR、AR交互工具包)记录安装到开发的流程,以及遇到的常见问题(一)!

提示&#xff1a;文章有错误的地方&#xff0c;还望诸位大神不吝指教&#xff01; 文章目录 前言一、XR Interaction Toolkit是什么&#xff1f;二、跨平台交互三、 AR 功能四、XR Interaction Toolkit的特点五、XR Interaction Toolkit 示例总结 前言 随着VR行业的发展&#…

移动设备安全革命:应对威胁与解决方案

移动设备已成为我们日常工作和家庭生活中不可或缺的工具&#xff0c;然而&#xff0c;对于它们安全性的关注和投资仍然远远不够。本文深入分析了移动设备安全的发展轨迹、目前面临的威胁态势&#xff0c;以及业界对于这些安全漏洞响应迟缓的深层原因。文中还探讨了人们在心理层…

Python酷库之旅-第三方库Pandas(030)

目录 一、用法精讲 79、pandas.Series.dtype属性 79-1、语法 79-2、参数 79-3、功能 79-4、返回值 79-5、说明 79-6、用法 79-6-1、数据准备 79-6-2、代码示例 79-6-3、结果输出 80、pandas.Series.shape属性 80-1、语法 80-2、参数 80-3、功能 80-4、返回值 …

2024杭电多校1——1008位运算

Problem Description 小丁最近对位运算很感兴趣&#xff0c;通过学习&#xff0c;他知道了按位与 ⊗&#xff0c;按位异或 ⊕&#xff0c;以及按位或 ⊖ 三种常见位运算。 按位与 ⊗&#xff1a;二进制下每一位做与&#xff0c;即 0⊗00,0⊗10,1⊗00,1⊗11。 按位异或 ⊕&am…

【MySQL】:想学好数据库,不知道这些还想咋学

客户端—服务器 客户端是一个“客户端—服务器”结构的程序 C&#xff08;client&#xff09;—S&#xff08;server&#xff09; 客户端和服务器是两个独立的程序&#xff0c;这两个程序之间通过“网络”进行通信&#xff08;相当于是两种角色&#xff09; 客户端 主动发起网…

SQL GROUPING运算符详解

在大数据开发中,我们经常需要对数据进行分组和汇总分析。 目录 1. GROUPING运算符概念2. 语法和用法3. 实际应用示例4. GROUPING运算符的优势5. 高级应用场景5.1 与CASE语句结合使用5.2 多维数据分析 6. 性能考虑和优化技巧7. GROUPING运算符的局限性8. 最佳实践9. GROUPING与其…

第6章 单片机的定时器/计数器

6.1 定时/计数器的结构与工作原理 6.2 定时器的控制 6.3 定时/计数器的工作方式 6.4 定时/计数器的编程和应用 6.1 定时/计数器的结构与工作原理 6.1.1 定时/计数器的基本原理 纯软件定时/计数方法&#xff1a; 定时——空循环预定周次&#xff0c;等待预定时间 计数—…

义务外贸wordpress独立站主题

健身器材wordpress网站模板 跑步机、椭圆机、划船机、动感单车、健身车、深蹲架、龙门架、健身器材wordpress网站模板。 https://www.jianzhanpress.com/?p4251 农业机械wordpress网站模板 植保机械、畜牧养殖机械、农机配件、土壤耕整机械、农业机械wordpress网站模板。 …

鸿蒙开发 03 封装 @ohos/axios (最新深度封装)

鸿蒙开发 03 封装 ohos/axios &#xff08;最新深度封装&#xff09; 1、安装 ohos/axios2、开始封装2.1 新建 utils 文件夹 和 api 文件夹2.2 在 utils 文件夹里新建 http.ts2.3 在 api 文件夹里新建 api.ets 3、页面调用4、打印结果 1、安装 ohos/axios ohpm install ohos/a…

Linux中进程的控制

一、进程的创建 1、知识储备 进程的创建要调用系统接口&#xff0c;头文件 #include<unistd.h> 函数fork() 由于之前的铺垫我们现在可以更新一个概念 进程 内核数据结构&#xff08;task_struct, mm_struct, 页表....&#xff09; 代码 数据 所以如何理解进程的独…

如何在 Odoo 16 中覆盖现有控制器

Odoo 中使用控制器来开发前端模块。后端模块链接到控制器。我们可以通过使用覆盖属性对基类进行修改来修改编程逻辑或向现有程序添加新逻辑。 要将控制器添加到模块,第一步,您必须为控制器创建一个单独的目录。在此目录中,应将一个 init 文件和包含控制器方法的所有 python…

Python中发送邮件的艺术:普通邮件、PDF附件与Markdown附件

用的是qq邮箱&#xff0c;具体获取smtp的password可以看这个文章 获取密码 Python中发送邮件的艺术&#xff1a;普通邮件、PDF附件与Markdown附件 在今天的博客中&#xff0c;我们将探讨如何使用Python的smtplib库来发送电子邮件&#xff0c;包括发送普通文本邮件、携带PDF文件…

初学 Linux 必知必会的 X 个知识点

文章目录 一、Linux 系统与 Windows 系统的差别二、Linux 命令行初识1. 终端界面2. 路径的含义3. 命令结构说明4. 常见的 Linux 命令4-1. 文件和目录操作4-2. 网络相关命令 5. 使用命令行时的小技巧5-1. 使用 TAB 键补全5-2. 巧用通配符 *5-3. 命令行历史功能 三、文件的详细信…

代码:前端与数据库交互的登陆界面

<!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>登录</title> </head> <body>…