Acwing 算法基础课 c++模板整理(附python语法基础题)(三)

简介: Acwing 算法基础课 c++模板整理(附python语法基础题)

贪心

区间选点

给定N个闭区间[ai,bi],请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n;
struct Range{
    int l, r;
    bool operator< (const Range &W)const{
        return r < W.r;
    }
}range[N];
int main(){
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ ) scanf("%d%d", &range[i].l, &range[i].r);
    sort(range, range + n);
    int res = 0, ed = -2e9;
    for (int i = 0; i < n; i ++ )
        if (range[i].l > ed){
            res ++ ;
            ed = range[i].r;
        }
    printf("%d\n", res);
    return 0;
}

最大不相交区间数量

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n;
struct Range{
    int l, r;
    bool operator< (const Range &W)const{
        return r < W.r;
    }
}range[N];
int main(){
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ ) scanf("%d%d", &range[i].l, &range[i].r);
    sort(range, range + n);
    int res = 0, ed = -2e9;
    for (int i = 0; i < n; i ++ )
        if (ed < range[i].l){
            res ++ ;
            ed = range[i].r;
        }
    printf("%d\n", res);
    return 0;
}

区间分组

给定N个闭区间 [ai,bi],请你将这些区间分成若干组,使得每组内部的区间两两之间(包括端点)没有交集,并使得组数尽可能小。

输出最小组数。

#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 100010;
int n;
struct Range{
    int l, r;
    bool operator< (const Range &W)const{
        return l < W.l;
    }
}range[N];
int main(){
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ ){
        int l, r;
        scanf("%d%d", &l, &r);
        range[i] = {l, r};
    }
    sort(range, range + n);
    priority_queue<int, vector<int>, greater<int>> heap;
    for (int i = 0; i < n; i ++ ){
        auto r = range[i];
        if (heap.empty() || heap.top() >= r.l) heap.push(r.r);
        else{
            heap.pop();
            heap.push(r.r);
        }
    }
    printf("%d\n", heap.size());
    return 0;
}

区间覆盖

给定N个闭区间ai,bi]以及一个线段区间 [s,t],请你选择尽量少的区间,将指定线段区间完全覆盖。

输出最少区间数,如果无法完全覆盖则输出 −1。

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n;
struct Range{
    int l, r;
    bool operator< (const Range &W)const{
        return l < W.l;
    }
}range[N];
int main(){
    int st, ed;
    scanf("%d%d", &st, &ed);
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ ){
        int l, r;
        scanf("%d%d", &l, &r);
        range[i] = {l, r};
    }
    sort(range, range + n);
    int res = 0;
    bool success = false;
    for (int i = 0; i < n; i ++ ){
        int j = i, r = -2e9;
        while (j < n && range[j].l <= st){
            r = max(r, range[j].r);
            j ++ ;
        }
        if (r < st){
            res = -1;
            break;
        }
        res ++ ;
        if (r >= ed){
            success = true;
            break;
        }
        st = r;
        i = j - 1;
    }
    if (!success) res = -1;
    printf("%d\n", res);
    return 0;
}

合并果子

#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
int main(){
    int n;
    scanf("%d", &n);
    priority_queue<int, vector<int>, greater<int>> heap;
    while (n -- ){
        int x;
        scanf("%d", &x);
        heap.push(x);
    }
    int res = 0;
    while (heap.size() > 1){
        int a = heap.top(); heap.pop();
        int b = heap.top(); heap.pop();
        res += a + b;
        heap.push(a + b);
    }
    printf("%d\n", res);
    return 0;
}

排队打水

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
int n;
int t[N];
int main(){
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ ) scanf("%d", &t[i]);
    sort(t, t + n);
    reverse(t, t + n);
    LL res = 0;
    for (int i = 0; i < n; i ++ ) res += t[i] * i;
    printf("%lld\n", res);
    return 0;
}

货仓选址

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n;
int q[N];
int main(){
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ ) scanf("%d", &q[i]);
    sort(q, q + n);
    int res = 0;
    for (int i = 0; i < n; i ++ ) res += abs(q[i] - q[n / 2]);
    printf("%d\n", res);
    return 0;
}

耍杂技的牛

农民约翰的N头奶牛(编号为1..N)计划逃跑并加入马戏团,为此它们决定练习表演杂技。

奶牛们不是非常有创意,只提出了一个杂技表演:

叠罗汉,表演时,奶牛们站在彼此的身上,形成一个高高的垂直堆叠。

奶牛们正在试图找到自己在这个堆叠中应该所处的位置顺序。

N头奶牛中的每一头都有着自己的重量Wi以及自己的强壮程度Si

一头牛支撑不住的可能性取决于它头上所有牛的总重量(不包括它自己)减去它的身体强壮程度的值,现在称该数值为风险值,风险值越大,这只牛撑不住的可能性越高。

您的任务是确定奶牛的排序,使得所有奶牛的风险值中的最大值尽可能的小。

#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int, int> PII;
const int N = 50010;
int n;
PII cow[N];
int main(){
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ ){
        int s, w;
        scanf("%d%d", &w, &s);
        cow[i] = {w + s, w};
    }
    sort(cow, cow + n);
    int res = -2e9, sum = 0;
    for (int i = 0; i < n; i ++ ){
        int s = cow[i].first - cow[i].second, w = cow[i].second;
        res = max(res, sum - s);
        sum += w;
    }
    printf("%d\n", res);
    return 0;
}

判断子序列

给定一个长度为nn的整数序列a1,a2,,an以及一个长度为m mm的整数序列b1,b2,,bm

请你判断a序列是否为b序列的子序列。

子序列指序列的一部分项按原有次序排列而得的序列,例如序列a1,a3,a5} 是序列a1,a2,a3,a4,a5} 的一个子序列。

#include <iostream>
#include <cstring>
using namespace std;
const int N = 100010;
int n, m;
int a[N], b[N];
int main(){
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
    for (int i = 0; i < m; i ++ ) scanf("%d", &b[i]);
    int i = 0, j = 0;
    while (i < n && j < m){
        if (a[i] == b[j]) i ++ ;
        j ++ ;
    }
    if (i == n) puts("Yes");
    else puts("No");
    return 0;
}

表达式求值

#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <unordered_map>
using namespace std;
stack<int> num;
stack<char> op;
void eval(){
    auto b = num.top(); num.pop();
    auto a = num.top(); num.pop();
    auto c = op.top(); op.pop();
    int x;
    if (c == '+') x = a + b;
    else if (c == '-') x = a - b;
    else if (c == '*') x = a * b;
    else x = a / b;
    num.push(x);
}
int main(){
    unordered_map<char, int> pr{{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};
    string str;
    cin >> str;
    for (int i = 0; i < str.size(); i ++ ){
        auto c = str[i];
        if (isdigit(c)){
            int x = 0, j = i;
            while (j < str.size() && isdigit(str[j]))
                x = x * 10 + str[j ++ ] - '0';
            i = j - 1;
            num.push(x);
        }
        else if (c == '(') op.push(c);
        else if (c == ')'){
            while (op.top() != '(') eval();
            op.pop();
        }
        else{
            while (op.size() && op.top() != '(' && pr[op.top()] >= pr[c]) eval();
            op.push(c);
        }
    }
    while (op.size()) eval();
    cout << num.top() << endl;
    return 0;
}

上机课

进制转换

将一个长度最多为 30 位数字的十进制非负整数转换为二进制数输出。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
vector<int> div(vector<int> A, int b){
    vector<int> C;
    for (int i = A.size() - 1, r = 0; i >= 0; i -- ){
        r = r * 10 + A[i];
        C.push_back(r / b);
        r %= b;
    }
    reverse(C.begin(), C.end());
    while (C.size() && C.back() == 0) C.pop_back();
    return C;
}
int main(){
    string s;
    while (cin >> s){
        vector<int> A;
        for (int i = 0; i < s.size(); i ++ )
            A.push_back(s[s.size() - i - 1] - '0');
        string res;
        if (s == "0") res = "0";
        else{
            while (A.size()){
                res += to_string(A[0] % 2);
                A = div(A, 2);
            }
        }
        reverse(res.begin(), res.end());
        cout << res << endl;
    }
    return 0;
}

3374. 进制转换2

将 M 进制的数 X 转换为 N 进制的数输出。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
int main(){
    int a, b;
    string s;
    cin >> a >> b >> s;
    vector<int> A;
    for (int i = 0; i < s.size(); i ++ ){
        char c = s[s.size() - 1 - i];
        if (c >= 'A') A.push_back(c - 'A' + 10);
        else A.push_back(c - '0');
    }
    string res;
    if (s == "0") res = "0";
    else{
        while (A.size()){
            int r = 0;
            for (int i = A.size() - 1; i >= 0; i -- ){
                A[i] += r * a;
                r = A[i] % b;
                A[i] /= b;
            }
            while (A.size() && A.back() == 0) A.pop_back();
            if (r < 10) res += to_string(r);
            else res += r - 10 + 'a';
        }
        reverse(res.begin(), res.end());
    }
    cout << res << endl;
    return 0;
}

重排链表

image.png

class Solution {
public:
    void rearrangedList(ListNode* head) {
        if (!head->next) return;
        int n = 0;
        for (auto p = head; p; p = p->next) n ++ ;
        int left = (n + 1) / 2;  // 前半段的节点数
        auto a = head;
        for (int i = 0; i < left - 1; i ++ ) a = a->next;
        auto b = a->next, c = b->next;
        a->next = b->next = NULL;
        while (c) {
            auto p = c->next;
            c->next = b;
            b = c, c = p;
        }
        for (auto p = head, q = b; q;) {
            auto o = q->next;
            q->next = p->next;
            p->next = q;
            p = p->next->next;
            q = o;
        }
    }
};

打印日期

给出年份 y 和一年中的第 d 天,算出第 d 天是几月几号。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int months[13] = {
    0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
int is_leap(int year){  // 闰年返回1,平年返回0
    if (year % 4 == 0 && year % 100 || year % 400 == 0)
        return 1;
    return 0;
}
int get_days(int y, int m){  // y年m月有多少天
    if (m == 2) return months[m] + is_leap(y);
    return months[m];
}
int main(){
    int y, s;
    while (cin >> y >> s){
        int m = 1, d = 1;
        s -- ;
        while (s -- ){
            if ( ++ d > get_days(y, m)){
                d = 1;
                if ( ++ m > 12){
                    m = 1;
                    y ++ ;
                }
            }
        }
        printf("%04d-%02d-%02d\n", y, m, d);
    }
    return 0;
}

日期累加

设计一个程序能计算一个日期加上若干天后是什么日期。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int months[13] = {
    0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
int is_leap(int year){
    if (year % 4 == 0 && year % 100 || year % 400 == 0)
        return 1;
    return 0;
}
int get_days(int y, int m){
    if (m == 2) return months[m] + is_leap(y);
    return months[m];
}
int get_year_days(int y, int m){
    if (m <= 2) return 365 + is_leap(y);
    return 365 + is_leap(y + 1);
}
int main(){
    int T;
    cin >> T;
    while (T -- ){
        int y, m, d, a;
        cin >> y >> m >> d >> a;
        if (m == 2 && d == 29) a --, m = 3, d = 1;
        while (a > get_year_days(y, m)){
            a -= get_year_days(y, m);
            y ++ ;
        }
        while (a -- ){
            if ( ++ d > get_days(y, m)){
                d = 1;
                if ( ++ m > 12){
                    m = 1;
                    y ++ ;
                }
            }
        }
        printf("%04d-%02d-%02d\n", y, m, d);
    }
    return 0;
}

二叉树的带权路径长度

二叉树的带权路径长度(WPL)是二叉树中所有叶结点的带权路径长度之和,也就是每个叶结点的深度与权值之积的总和。

class Solution {
public:
    int dfs(TreeNode* root, int depth) {
        if (!root) return 0;
        if (!root->left && !root->right) return root->val * depth;
        return dfs(root->left, depth + 1) + dfs(root->right, depth + 1);
    }
    int pathSum(TreeNode* root) {
        return dfs(root, 0);
    }
};

二叉排序树

你需要写一种数据结构,来维护一些数,其中需要提供以下操作:

插入数值 x。

删除数值 x。

输出数值 x 的前驱(前驱定义为现有所有数中小于 x 的最大的数)。

输出数值 x 的后继(后继定义为现有所有数中大于 x 的最小的数)。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 1e8;
struct TreeNode{
    int val;
    TreeNode *left, *right;
    TreeNode(int _val): val(_val), left(NULL), right(NULL) {}
}*root;
void insert(TreeNode* &root, int x){
    if (!root) root = new TreeNode(x);
    else if (x < root->val) insert(root->left, x);
    else insert(root->right, x);
}
void remove(TreeNode* &root, int x){
    if (!root) return;
    if (x < root->val) remove(root->left, x);
    else if (x > root->val) remove(root->right, x);
    else{
        if (!root->left && !root->right) root = NULL;
        else if (!root->left) root = root->right;
        else if (!root->right) root = root->left;
        else{
            auto p = root->left;
            while (p->right) p = p->right;
            root->val = p->val;
            remove(root->left, p->val);
        }
    }
}
int get_pre(TreeNode* root, int x){
    if (!root) return -INF;
    if (root->val >= x) return get_pre(root->left, x);
    return max(root->val, get_pre(root->right, x));
}
int get_suc(TreeNode* root, int x){
    if (!root) return INF;
    if (root->val <= x) return get_suc(root->right, x);
    return min(root->val, get_suc(root->left, x));
}
int main(){
    int n;
    cin >> n;
    while (n -- ){
        int t, x;
        cin >> t >> x;
        if (t == 1) insert(root, x);
        else if (t == 2) remove(root, x);
        else if (t == 3) cout << get_pre(root, x) << endl;
        else cout << get_suc(root, x) << endl;
    }
    return 0;
}

表达式树

请设计一个算法,将给定的表达式树(二叉树)转换为等价的中缀表达式(通过括号反映操作符的计算次序)并输出。

class Solution {
public:
    string dfs(TreeNode* root) {
        if (!root) return "";
        if (!root->left && !root->right) return root->val;
        return '(' + dfs(root->left) + root->val + dfs(root->right) + ')';
    }
    string expressionTree(TreeNode* root) {
        return dfs(root->left) + root->val + dfs(root->right);
    }
};

未出现过的最小正整数

给定一个长度为 n 的整数数组,请你找出未在数组中出现过的最小正整数。

class Solution {
public:
    int findMissMin(vector<int>& nums) {
        int n = nums.size();
        vector<bool> hash(n + 1);
        for (int x: nums)
            if (x >= 1 && x <= n)
                hash[x] = true;
        for (int i = 1; i <= n; i ++ )
            if (!hash[i])
                return i;
        return n + 1;
    }
};

三元组的最小距离

image.png

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
int l, m, n;
int a[N], b[N], c[N];
int main(){
    scanf("%d%d%d", &l, &m, &n);
    for (int i = 0; i < l; i ++ ) scanf("%d", &a[i]);
    for (int i = 0; i < m; i ++ ) scanf("%d", &b[i]);
    for (int i = 0; i < n; i ++ ) scanf("%d", &c[i]);
    LL res = 1e18;
    for (int i = 0, j = 0, k = 0; i < l && j < m && k < n;){
        int x = a[i], y = b[j], z = c[k];
        res = min(res, (LL)max(max(x, y), z) - min(min(x, y), z));
        if (x <= y && x <= z) i ++ ;
        else if (y <= x && y <= z) j ++ ;
        else k ++ ;
    }
    printf("%lld\n", res * 2);
    return 0;
}

众数

给定一个整数序列,其中包含 n 个非负整数,其中的每个整数都恰好有 m 位,从最低位到最高位,依次编号为 1∼m 位。

现在,请你统计该序列各个位的众数。

第 i 位的众数是指,在给定的 n 个整数的第 i 位上,出现次数最多的最小数字。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int s[6][10];
int main(){
    int n, m;
    scanf("%d%d", &n, &m);
    while (n -- ){
        int x;
        scanf("%d", &x);
        for (int i = 0; i < m; i ++ ){
            s[i][x % 10] ++ ;
            x /= 10;
        }
    }
    for (int i = 0; i < m; i ++ ){
      int k = 0;
        for (int j = 0; j < 10; j ++ )
            if (s[i][k] < s[i][j])
                k = j;
        printf("%d\n", k);
    }
    return 0;
}

玛雅人的密码

玛雅人有一种密码,如果字符串中出现连续的 2012 四个数字就能解开密码。

给定一个长度为 N 的字符串,该字符串中只含有 0,1,2 三种数字。

可以对该字符串进行移位操作,每次操作可选取相邻的两个数字交换彼此位置。

请问这个字符串要移位几次才能解开密码。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <unordered_map>
using namespace std;
int n;
int bfs(string start){
    queue<string> q;
    unordered_map<string, int> dist;
    dist[start] = 0;
    q.push(start);
    while (q.size()){
        auto t = q.front();
        q.pop();
        for (int i = 0; i < n; i ++ )
            if (t.substr(i, 4) == "2012")
                return dist[t];
        for (int i = 1; i < n; i ++ ){
            string r = t;
            swap(r[i], r[i - 1]);
            if (!dist.count(r)){
                dist[r] = dist[t] + 1;
                q.push(r);
            }
        }
    }
    return -1;
}
int main(){
    string start;
    cin >> n >> start;
    cout << bfs(start) << endl;
    return 0;
}

等差数列

有一个特殊的nm列的矩阵 Aij,每个元素都是正整数,每一行和每一列都是独立的等差数列。

在某一次故障中,这个矩阵的某些元素的真实值丢失了,被重置为 0。

现在需要你想办法恢复这些元素,并且按照行号和列号从小到大的顺序(行号为第一关键字,列号为第二关键字,从小到大)输出能够恢复的元素。

#include<bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
const int N = 1010;
int n, m, a[N][N], r[N][4], c[N][4];
queue<int> q;
//给坐标[i, j]赋值为x
//同时判断第i 行是否有两个点,第j 列是否有两个点
void add(int i, int j, int x){
    a[i][j] = x;
    //如果第i 行一个点都没有,给定第一个点的值到r[i][0],列数为r[i][1]
    //其次如果第i 行没第二个点,给定第二个点的值到r[i][2],列数为r[i][3],并且加入到bfs中
    //如果还有第三个点其实就不进行操作
    if(!r[i][0]) r[i][0] = x, r[i][1] = j;
    else if(!r[i][2]) r[i][2] = x, r[i][3] = j, q.push(i * 2 + 1);//如果是行扩展,加入奇数
    //对列进行同等操作
    if(!c[j][0]) c[j][0] = x, c[j][1] = i;
    else if(!c[j][2]) c[j][2] = x, c[j][3] = i, q.push(j * 2);//如果是列扩展,加入偶数
}
int main(){
    cin >> n >> m;
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++){
            int x;
            scanf("%d",&x);
            if(x) add(i, j, x);//给[i, j] 赋值 x
        }
    vector<pii> ans;//frist 里面存[x, y]坐标,sceond里面存值
    while(q.size()){
        int now = q.front() / 2, f = q.front() % 2; q.pop();//取出行号或者列号
        if(f){//如果是行扩展
            int suf = (r[now][2] - r[now][0]) / (r[now][3] - r[now][1]);//得到等差值
            int start = r[now][0] - (r[now][1] * suf);//求得第一个点的值
            for(int i = 0; i < m; i++){
                if(!a[now][i]){//如果a[now][i]是0,将a[now][i]按照等差公式赋值
                    add(now, i, start + i * suf);//赋值
                    ans.push_back({now * 2000 + i, start + i * suf});//加入[坐标,值]答案数组中
                }
            }
        }
        else{//列扩展,以下同理
            int suf = (c[now][2] - c[now][0]) / (c[now][3] - c[now][1]);
            int start = c[now][0] - (c[now][1] * suf);
            for(int i = 0; i < n; i++){
                if(!a[i][now]){
                    add(i, now, start + i * suf);
                    ans.push_back({i * 2000 + now, start + i * suf});
                }
            }
        }
    }
    sort(ans.begin(), ans.end());//按照坐标排序
    for(auto [xy, val] : ans){
        printf("%d %d %d\n",xy/2000+1,xy%2000+1,val);//输出答案
    }
    return 0;
}

3441. 重复者

给定一个仅包含一种字符和空格的模板,将之不断重复扩大。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
int n;
vector<string> p;
vector<string> g(int k){
    if (k == 1) return p;
    auto s = g(k - 1);
    int m = s.size();
    vector<string> res(n * m);
    for (int i = 0; i < n * m; i ++ )
        res[i] = string(n * m, ' ');
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < n; j ++ )
            if (p[i][j] != ' ')
                for (int x = 0; x < m; x ++ )
                    for (int y = 0; y < m; y ++ )
                        res[i * m + x][j * m + y] = s[x][y];
    return res;
}
int main(){
    while (cin >> n, n){
        p.clear();
        getchar();  // 读掉n后的回车
        for (int i = 0; i < n; i ++ ){
            string line;
            getline(cin, line);
            p.push_back(line);
        }
        int k;
        cin >> k;
        auto res = g(k);
        for (auto& s: res) cout << s << endl;
    }
    return 0;
}

3382. 整数拆分

一个整数总可以拆分为 2 的幂的和

用 f(n) 表示 n 的不同拆分的种数,例如 f(7)=6。

要求编写程序,读入 n,输出 f(n)mod1e9

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1000010, MOD = 1e9;
int n;
int f[N];
int main(){
    scanf("%d", &n);
    f[0] = 1;
    for (int i = 1; i <= n; i *= 2)
        for (int j = i; j <= n; j ++ )
            f[j] = (f[j] + f[j - i]) % MOD;
    cout << f[n] << endl;
    return 0;
}

位操作练习

给出两个不大于 65535 的非负整数,判断其中一个的 16 位二进制表示形式,是否能由另一个的 16 位二进制表示形式经过循环左移若干位而得到。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main(){
    int a, b;
    while (cin >> a >> b){
        string x, y;
        for (int i = 15; i >= 0; i -- ){
            x += to_string(a >> i & 1);
            y += to_string(b >> i & 1);
        }
        y += y;
        if (y.find(x) != -1) puts("YES");
        else puts("NO");
    }
    return 0;
}

最小面积子矩阵

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110, INF = 100000;
int n, m, k;
int s[N][N];
int main(){
    cin >> n >> m >> k;
    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= m; j ++ ){
            cin >> s[i][j];
            s[i][j] += s[i - 1][j];
        }
    int res = INF;
    for (int x = 1; x <= n; x ++ )
        for (int y = x; y <= n; y ++ ){
            for (int i = 1, j = 1, sum = 0; i <= m; i ++ ){
                sum += s[y][i] - s[x - 1][i];
                while (sum - (s[y][j] - s[x - 1][j]) >= k){
                    sum -= s[y][j] - s[x - 1][j];
                    j ++ ;
                }
                if (sum >= k) res = min(res, (y - x + 1) * (i - j + 1));
            }
        }
    if (res == INF) res = -1;
    cout << res << endl;
    return 0;
}

矩阵幂

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 15;
int n, m;
int w[N][N];
void mul(int c[][N], int a[][N], int b[][N]){
    static int tmp[N][N];
    memset(tmp, 0, sizeof tmp);
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < n; j ++ )
            for (int k = 0; k < n; k ++ )
                tmp[i][j] += a[i][k] * b[k][j];
    memcpy(c, tmp, sizeof tmp);
}
int main(){
    cin >> n >> m;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < n; j ++ )
            cin >> w[i][j];
    int res[N][N] = {0};
    for (int i = 0; i < n; i ++ ) res[i][i] = 1;
    while (m -- ) mul(res, res, w);
    for (int i = 0; i < n; i ++ ){
        for (int j = 0; j < n; j ++ )
            cout << res[i][j] << ' ';
        cout << endl;
    }
    return 0;
}

C翻转

给定一个 5×5 的矩阵,对其进行翻转操作。

操作类型共四种,具体形式如下:

1 2 x y,表示将以第 x 行第 y 列的元素为左上角,边长为 2 的子矩阵顺时针翻转 90 度。

1 3 x y,表示将以第 x 行第 y 列的元素为左上角,边长为 3 的子矩阵顺时针翻转 90 度。

2 2 x y,表示将以第 x 行第 y 列的元素为左上角,边长为 2 的子矩阵逆时针翻转 90 度。

2 3 x y,表示将以第 x 行第 y 列的元素为左上角,边长为 3 的子矩阵逆时针翻转 90 度。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 5;
int n;
int g[N][N];
void rotate(int x, int y, int m){
    int w[N][N];
    memcpy(w, g, sizeof g);
    for (int i = 0; i < m; i ++ )
        for (int j = 0, k = m - 1; j < m; j ++, k -- )
            w[i][j] = g[x + k][y + i];
    for (int i = 0; i < m; i ++ )
        for (int j = 0; j < m; j ++ )
            g[x + i][y + j] = w[i][j];
}
int main(){
    for (int i = 0; i < 5; i ++ )
        for (int j = 0; j < 5; j ++ )
            cin >> g[i][j];
    int a, b, x, y;
    cin >> a >> b >> x >> y;
    x --, y -- ;
    if (a == 1) rotate(x, y, b);
    else{
        for (int i = 0; i < 3; i ++ )
            rotate(x, y, b);
    }
    for (int i = 0; i < 5; i ++ ){
        for (int j = 0; j < 5; j ++ )
            cout << g[i][j] << ' ';
        cout << endl;
    }
    return 0;
}

最长平衡串

给定一个只含 01 的字符串,找出它的最长平衡子串的长度。

如果一个 01 字符串包含的 0 和 1 的个数相同,则称其为平衡串。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
using namespace std;
const int N = 1000010;
int n;
char str[N];
int main(){
    scanf("%s", str + 1);
    unordered_map<int, int> hash;
    n = strlen(str + 1);
    int res = 0;
    hash[0] = 0;
    for (int i = 1, s = 0; i <= n; i ++ ){
        if (str[i] == '0') s ++ ;
        else s -- ;
        if (hash.count(s)) res = max(res, i - hash[s]);
        else hash[s] = i;
    }
    printf("%d\n", res);
    return 0;
}

Python

读取四个整数 A,B,C,D,并计算 (A×B−C×D) 的值。

a = int(input())
b = int(input())
c = int(input())
d = int(input())
print("DIFERENCA = %d" % (a * b - c * d))

倍数

a, b = map(int, input().split(' '))
if a % b == 0 or b % a == 0:
    print("Sao Multiplos")
else:
    print("Nao sao Multiplos")

零食

x, y = map(int, input().split(' '))
prices = [0, 4, 4.5, 5, 2, 1.5]
print("Total: R$ %.2lf" % (prices[x] * y))

字符串长度

print(len(input()))

递增序列

while True:
    x = int(input())
    if x == 0:
        break
    for i in range(1, x + 1):
        print(i, end=' ')
    print()

质数

import math
n = int(input())
for i in range(n):
    x = int(input())
    for j in range(2, int(math.sqrt(x)) + 1):
        if x % j == 0:
            print(x, "is not prime")
            break
    else:
        print(x, "is prime")

数组的右上

t = input()
s, c = 0, 0
for i in range(12):
    d = list(map(float, input().split(' ')))
    for j in range(12):
        if j > i:
            s += d[j]
            c += 1
if t == "M":
    s /= c
print("%.1f" % (s))

蛇形矩阵

n, m = map(int, input().split())
res = [[0 for j in range(m)] for i in range(n)]
dx, dy = [-1, 0, 1, 0], [0, 1, 0, -1]
x, y, d = 0, 0, 1
for i in range(1, n * m + 1):
    res[x][y] = i
    a, b = x + dx[d], y + dy[d]
    if a < 0 or a >= n or b < 0 or b >= m or res[a][b]:
        d = (d + 1) % 4
        a, b = x + dx[d], y + dy[d]
    x, y = a, b
for i in range(n):
    for j in range(m):
        print(res[i][j], end = ' ')
    print()

排列

n = int(input())
path = [0 for i in range(n)]
used = [False for i in range(n)]
def dfs(u):
    if u == n:
        for i in range(n):
            print(path[i] + 1, end=' ')
        print()
    else:
        for i in range(n):
            if not used[i]:
                path[u] = i
                used[i] = True
                dfs(u + 1)
                used[i] = False
                path[u] = 0
dfs(0)

a+b

#输入无行数限制
while True:
    try:
        a, b = map(int, input().split())
        print(a + b)
    except:
        break
#先输入行数
n = int(input())
while n:
    a, b = map(int, input().split())
    print(a + b)
    n -= 1
#输入00结束
while True:
    a, b = map(int, input().split())
    if a != 0 and b != 0: print(a + b)
    else: break

行内数组求和

#给定数组长度,输入0停止
while True:
    arr = list(map(int, input().split()))
    if arr[0] == 0: break
    else: print(sum(arr[1:]))
#给定总数组数量
n = int(input())
while n:
    print(sum(list(map(int, input().split()))[1:]))
    n -= 1
#不给定总数组数量
while True:
    try:  # 对于没有行提示的,使用try except就很简单
        print(sum(list(map(int, input().split()))[1:]))
    except:
        break
# 不给行数和每行数组长度
while True:
    try:
        print(sum(list(map(int, input().split()))))
    except:
        break

字符串排序

#给定字符数量
n = int(input())
arr = input().split()
arr.sort()
print(' '.join(arr))
#不给定字符数量
while True:
    try:
        arr = input().split()
        arr.sort()
        print(" ".join(arr))
    except:
        break
#逗号分割
while True:
    try:
        arr = input().split(",")
        arr.sort()
        print(",".join(arr))
    except:
        break


目录
打赏
0
0
0
0
54
分享
相关文章
解读 C++ 助力的局域网监控电脑网络连接算法
本文探讨了使用C++语言实现局域网监控电脑中网络连接监控的算法。通过将局域网的拓扑结构建模为图(Graph)数据结构,每台电脑作为顶点,网络连接作为边,可高效管理与监控动态变化的网络连接。文章展示了基于深度优先搜索(DFS)的连通性检测算法,用于判断两节点间是否存在路径,助力故障排查与流量优化。C++的高效性能结合图算法,为保障网络秩序与信息安全提供了坚实基础,未来可进一步优化以应对无线网络等新挑战。
基于 C++ 语言的迪杰斯特拉算法在局域网计算机管理中的应用剖析
在局域网计算机管理中,迪杰斯特拉算法用于优化网络路径、分配资源和定位故障节点,确保高效稳定的网络环境。该算法通过计算最短路径,提升数据传输速率与稳定性,实现负载均衡并快速排除故障。C++代码示例展示了其在网络模拟中的应用,为企业信息化建设提供有力支持。
46 15
公司局域网管理中的哈希表查找优化 C++ 算法探究
在数字化办公环境中,公司局域网管理至关重要。哈希表作为一种高效的数据结构,通过哈希函数将关键值(如IP地址、账号)映射到数组索引,实现快速的插入、删除与查找操作。例如,在员工登录验证和设备信息管理中,哈希表能显著提升效率,避免传统线性查找的低效问题。本文以C++为例,展示了哈希表在局域网管理中的具体应用,包括设备MAC地址与IP分配的存储与查询,并探讨了优化哈希函数和扩容策略,确保网络管理高效准确。
如何在Python下实现摄像头|屏幕|AI视觉算法数据的RTMP直播推送
本文详细讲解了在Python环境下使用大牛直播SDK实现RTMP推流的过程。从技术背景到代码实现,涵盖Python生态优势、AI视觉算法应用、RTMP稳定性及跨平台支持等内容。通过丰富功能如音频编码、视频编码、实时预览等,结合实际代码示例,为开发者提供完整指南。同时探讨C接口转换Python时的注意事项,包括数据类型映射、内存管理、回调函数等关键点。最终总结Python在RTMP推流与AI视觉算法结合中的重要性与前景,为行业应用带来便利与革新。
基于 Python 哈希表算法的员工上网管理策略研究
于当下数字化办公环境而言,员工上网管理已成为企业运营管理的关键环节。企业有必要对员工的网络访问行为予以监控,以此确保信息安全并提升工作效率。在处理员工上网管理相关数据时,适宜的数据结构与算法起着举足轻重的作用。本文将深入探究哈希表这一数据结构在员工上网管理场景中的应用,并借助 Python 代码示例展开详尽阐述。
31 3
Python下的毫秒级延迟RTSP|RTMP播放器技术探究和AI视觉算法对接
本文深入解析了基于Python实现的RTSP/RTMP播放器,探讨其代码结构、实现原理及优化策略。播放器通过大牛直播SDK提供的接口,支持低延迟播放,适用于实时监控、视频会议和智能分析等场景。文章详细介绍了播放控制、硬件解码、录像与截图功能,并分析了回调机制和UI设计。此外,还讨论了性能优化方法(如硬件加速、异步处理)和功能扩展(如音量调节、多格式支持)。针对AI视觉算法对接,文章提供了YUV/RGB数据处理示例,便于开发者在Python环境下进行算法集成。最终,播放器凭借低延迟、高兼容性和灵活扩展性,为实时交互场景提供了高效解决方案。
探秘文件共享服务之哈希表助力 Python 算法实现
在数字化时代,文件共享服务不可或缺。哈希表(散列表)通过键值对存储数据,利用哈希函数将键映射到特定位置,极大提升文件上传、下载和搜索效率。例如,在大型文件共享平台中,文件名等信息作为键,物理地址作为值存入哈希表,用户检索时快速定位文件,减少遍历时间。此外,哈希表还用于文件一致性校验,确保传输文件未被篡改。以Python代码示例展示基于哈希表的文件索引实现,模拟文件共享服务的文件索引构建与检索功能。哈希表及其分布式变体如一致性哈希算法,保障文件均匀分布和负载均衡,持续优化文件共享服务性能。
|
25天前
|
公司电脑网络监控场景下 Python 广度优先搜索算法的深度剖析
在数字化办公时代,公司电脑网络监控至关重要。广度优先搜索(BFS)算法在构建网络拓扑、检测安全威胁和优化资源分配方面发挥重要作用。通过Python代码示例展示其应用流程,助力企业提升网络安全与效率。未来,更多创新算法将融入该领域,保障企业数字化发展。
42 10
|
26天前
|
基于 Python 广度优先搜索算法的监控局域网电脑研究
随着局域网规模扩大,企业对高效监控计算机的需求增加。广度优先搜索(BFS)算法凭借其层次化遍历特性,在Python中可用于实现局域网内的计算机设备信息收集、网络连接状态监测及安全漏洞扫描,确保网络安全与稳定运行。通过合理选择数据结构与算法,BFS显著提升了监控效能,助力企业实现智能化的网络管理。
28 7
套用算法模板备案审核问题增多的原因及解决建议
随着算法备案要求的完善,企业常因使用网上廉价模板而遭遇审核通过率低、问题增多的困境。本文分析了审核不通过的原因,包括模板缺乏针对性、审核标准严格、审核人员主观差异及企业准备不足等,并提出建议:深入了解备案要求、准备详尽材料、避免通用模板、寻求专业帮助。备案后还需持续合规管理,确保算法服务安全运行。

热门文章

最新文章