真题2

数量级和复杂度

image

全排列好东西

#include <iostream>
#include <vector>
#include <algorithm>

// 使用std命名空间,简化代码书写
using namespace std;

int main() {
    vector<int> nums = {1, 2, 3};
    
    // 先排序,确保从最小的排列开始
    sort(nums.begin(), nums.end());
    
    do {
        // 输出当前排列
        for (int num : nums) {
            cout << num << " ";
        }
        cout << endl;
    } while (next_permutation(nums.begin(), nums.end()));
    // 每次调用next_permutation会修改nums为下一个排列
    
    return 0;
}

众数

题目描述

n 个序列(依次编号为 0, 1, ..., n-1),初始时各个序列均为空。你的任务是维护这 n 个序列,需支持以下三种操作:

  1. 操作 1 i k x:在第 i 个序列的末尾插入 k 个值均为 x 的数。
  2. 操作 2 i k:删除第 i 个序列末尾的 k 个数;若该序列的元素总数不足 k,则删除序列中所有剩余的数。
  3. 操作 3 i:询问第 i 个序列的众数。其中,众数定义为序列中出现次数最多的数;若存在多个数出现次数相同且均为最大值,则取其中数值最小的数。

输入格式

从标准输入读入数据,格式如下:

  • 第一行:两个正整数 nq,分别表示序列的个数和操作的总次数。
  • 接下来 q 行:每行描述一个操作,操作格式与题目描述一致(具体参数含义见“题目描述”中的操作说明)。

输出格式

输出到标准输出,规则如下:

  • 仅对“操作 3”(查询众数)进行输出:对于每个操作 3,输出当前第 i 个序列的众数,并换行。
  • 若查询时第 i 个序列为空(无有效元素),输出 -1

题解

主要涉及了哈希表和集合的使用技巧,提升效率。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<unordered_map>
#include<set>
using namespace std;
typedef long long LL;
typedef vector<LL> VI;
typedef vector<VI> VVI;
typedef pair<LL,LL> PII;
const int INF = 0x3f3f3f3f;
const LL INF_LL = 0x3f3f3f3f3f3f3f3f;
const double EPS = 1e-8;
const int MOD = 1e9 + 7;
const int MAXN = 2e5 + 10;

bool compareb(PII&a, PII&b){
    return a.second < b.second;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int n,q;
    cin >> n >> q;
    vector<vector<PII>> A(n);
    vector<unordered_map<LL,LL>> H(n);
    vector<set<PII>> S(n);
    // 使用unoerderedmap省去统计时间
    // 使用set自动排序!只有移除与插入,严格弱,第一个相等,就比较第一个小的先,升序
    // 集合为0的要擦出避免影响
    // 构造数据多个同个的能发现问题
    LL idx, k , x;
    LL oldacc;
    int opt;
    for(int i = 0; i < q; i++){
        cin >> opt;
        if(opt == 1){
            cin >> idx >> k >> x;
            A[idx].push_back({k,x});
            // occ用-的是因为当时加入的时候是-的这里直接弄成这样了
            oldacc = H[idx][x];
            H[idx][x] += k;     
            if(oldacc > 0){
                S[idx].erase({-oldacc, x});
            }
            S[idx].insert({-H[idx][x], x});
        }
        else if(opt == 2){
            cin >> idx >> k;
            LL tail = A[idx].size() -1;
            while(k>0&&A[idx].size()>0){
                if(A[idx][tail].first >= k){
                    // 这里写错了,本来,应该写累加的H的而不是A里的
                    oldacc = H[idx][A[idx][tail].second];
                    A[idx][tail].first -= k;
                    H[idx][A[idx][tail].second] -= k;
                    S[idx].erase({-oldacc, A[idx][tail].second});
                    if(H[idx][A[idx][tail].second]>0) S[idx].insert({-H[idx][A[idx][tail].second], A[idx][tail].second});
                    k = 0;
                }else{
                    oldacc = H[idx][A[idx][tail].second];
                    S[idx].erase({-oldacc, A[idx][tail].second});
                    k -= A[idx][tail].first;
                    H[idx][A[idx][tail].second] -= A[idx][tail].first;
                    A[idx].erase(A[idx].begin()+tail);
                    if(H[idx][A[idx][tail].second]>0) S[idx].insert({-H[idx][A[idx][tail].second], A[idx][tail].second});
                    tail --;
                }
            }
        }
        else if(opt == 3){
            cin >> idx;
            LL minme = -1;
            for(auto now:S[idx]){
                minme = now.second;
                break;
            }
            cout << minme << endl;
        }
    }

    return 0;
}

找到第一个没出现的自然数

代码丢了,大概就是排序,不是0开始就是输出0,否则开始遍历,如果出现相减大于1那么上一个+1就是答案。

整数对

找到x然后直接加起来(找到数字对i<j且i+j<=m的个数)

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<unordered_map>
#include<set>
// 可根据题目需求补充其他头文件(如<queue>、<stack>、<map>等)
using namespace std;

// -------------------------- 常用类型别名(简化代码)--------------------------
typedef long long LL;         // 处理大整数,避免溢出
typedef vector<LL> VI;        // 一维长整型数组
typedef vector<VI> VVI;       // 二维长整型数组
typedef pair<LL, LL> PII;     // 存储二元组(如<数量, 值>、<坐标x, 坐标y>)
// 可扩展:如typedef pair<int, int> PII_int;(int型二元组)、typedef vector<PII> VPII;(二元组数组)

// -------------------------- 通用常量定义(根据题目调整值)--------------------------
const int INF = 0x3f3f3f3f;        // int型最大值(常用于表示“无穷大”)
const LL INF_LL = 0x3f3f3f3f3f3f3f3f;  // long long型最大值
const double EPS = 1e-8;           // 浮点数精度(处理浮点数比较时用)
const LL MOD = 1e9 + 7;           // 常用模值(数论题、计数题常用)
const int MAXN = 2e5 + 10;         // 数组/容器最大规模(根据题目数据范围调整)

bool cmp(PII& a, PII& b) {
    return a.second < b.second;
}


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    LL n, m;
    cin >> n >> m;
    VI A(n);
    LL now, x, idx, count = 0;
    for(int i =0;i<n;i++){cin >> now; A[i] = -now;}
    // 反着读入方便下面处理
    sort(A.begin(),A.end());
    // 确定一个数 now,然后找到另一个最大数 x 使得 x + now 恰好<=m
    // 然后x以及之前的全部数字就可以构成对,纳入记录
    for(int i =n-1;i>=0;i--){
        now = -A[i];
        if(m<now)break;
        x = m - now;
        x = -x;
        auto it = lower_bound(A.begin(), A.end()+i, x);
        idx = it - A.begin();
        if(idx < i && idx >= 0){
            idx = i - idx;
            count += idx;
            count %= MOD;
        }
    }
    cout << count << endl;
    return 0;
}

movie

在万年历吃过亏,不过问题不大,用数组代替重复判断。
题目是把时间乘以帧率输出。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<unordered_map>
#include<set>
// 可根据题目需求补充其他头文件(如<queue>、<stack>、<map>等)
using namespace std;

// -------------------------- 常用类型别名(简化代码)--------------------------
typedef long long LL;         // 处理大整数,避免溢出
typedef vector<LL> VI;        // 一维长整型数组
typedef vector<VI> VVI;       // 二维长整型数组
typedef pair<LL, LL> PII;     // 存储二元组(如<数量, 值>、<坐标x, 坐标y>)
// 可扩展:如typedef pair<int, int> PII_int;(int型二元组)、typedef vector<PII> VPII;(二元组数组)

// -------------------------- 通用常量定义(根据题目调整值)--------------------------
const int INF = 0x3f3f3f3f;        // int型最大值(常用于表示“无穷大”)
const LL INF_LL = 0x3f3f3f3f3f3f3f3f;  // long long型最大值
const double EPS = 1e-8;           // 浮点数精度(处理浮点数比较时用)
const int MOD = 1e9 + 7;           // 常用模值(数论题、计数题常用)
const int MAXN = 2e5 + 10;         // 数组/容器最大规模(根据题目数据范围调整)

bool cmp(PII& a, PII& b) {
    return a.second < b.second;
}


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    LL T;
    cin >> T;
    string time;
    LL fps;
    LL ok = 3600 , now = 0, sum = 0;
    int i = 1;
    int M[2] = {1, 10};//用数组替代判断case
    while(T--){
        cin >> time >>fps;
        ok = 3600; now = 0; sum = 0; i = 1;
        for(char x : time){
            if(x ==':'){
                i = 1;
                sum += now * ok;
                ok /= 60;
                now = 0;
                continue;
            }
            now += (x - '0') * M[i];
            i--;
        }
        sum += now;
        fps *= sum;
        cout << fps << endl;
    }
    return 0;
}

理发店

来人,洗头/剪头时间,先洗头发才能剪头发,求最少时间。
要有这种抽象的编程思想。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<unordered_map>
#include<set>
// 可根据题目需求补充其他头文件(如<queue>、<stack>、<map>等)
using namespace std;

// -------------------------- 常用类型别名(简化代码)--------------------------
typedef long long LL;         // 处理大整数,避免溢出
typedef vector<LL> VI;        // 一维长整型数组
typedef vector<VI> VVI;       // 二维长整型数组
typedef pair<LL, LL> PII;     // 存储二元组(如<数量, 值>、<坐标x, 坐标y>)
// 可扩展:如typedef pair<int, int> PII_int;(int型二元组)、typedef vector<PII> VPII;(二元组数组)

// -------------------------- 通用常量定义(根据题目调整值)--------------------------
const int INF = 0x3f3f3f3f;        // int型最大值(常用于表示“无穷大”)
const LL INF_LL = 0x3f3f3f3f3f3f3f3f;  // long long型最大值
const double EPS = 1e-8;           // 浮点数精度(处理浮点数比较时用)
const int MOD = 1e9 + 7;           // 常用模值(数论题、计数题常用)
const int MAXN = 2e5 + 10;         // 数组/容器最大规模(根据题目数据范围调整)

vector<PII> S;
vector<PII> path;
vector<bool> used;
set<LL> ans;
LL temp;
int j;
int n;
PII x;
// 用dfs遍历所有情况
bool cmp(PII& a, PII& b) {
    return a.second < b.second;
}
//我这里正确性出问题了,需要修改,弄成两个并列了,其实还有很多
void check(){
        LL washend = 0, cutend = 0;
        for(auto x: path){
            LL a = x.first;
            LL b = x.second;
            // 开始洗头的时间就是洗头结束时间
            LL start = washend;
            washend = start + a;//洗头结束的时间就是他开始的加上他的洗头时间
            start = max(washend, cutend);//开始剪头的时间就是其中哪个先完成的
            cutend = start + b;
        }
        ans.insert(cutend);
}

//dfs说是
void work(){
    if(path.size()==n){
        check();
        return;
    }
    for(int i = 0; i < n; i++){
        if(used[i]==false){
            path.push_back(S[i]);
            used[i]=true;
            work();
            used[i]=false;
            path.pop_back();
        }
    }
}

// 多组数据情况记得清空
// 如果n小直接暴力!!!因为就没有更好的解法。。
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    LL T, a, b;

    cin >> T;
    while(T--){
        S.clear();
        used.clear();
        path.clear();
        cin >> n;
        for(int i = 0; i < n; i++){
            cin >> a >> b;
            S.push_back({a,b});
        }
        used.resize(n);
        work();
        cout << *ans.begin() << endl;//访问set第一个用解引用
        //for(auto x:ans) cout << x <<" ";
        ans.clear();
    }
    return 0;
}

五子棋模拟

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<unordered_map>
#include<set>
// 可根据题目需求补充其他头文件(如<queue>、<stack>、<map>等)
using namespace std;

// -------------------------- 常用类型别名(简化代码)--------------------------
typedef long long LL;         // 处理大整数,避免溢出
typedef vector<LL> VI;        // 一维长整型数组
typedef vector<VI> VVI;       // 二维长整型数组
typedef pair<LL, LL> PII;     // 存储二元组(如<数量, 值>、<坐标x, 坐标y>)
// 可扩展:如typedef pair<int, int> PII_int;(int型二元组)、typedef vector<PII> VPII;(二元组数组)

// -------------------------- 通用常量定义(根据题目调整值)--------------------------
const int INF = 0x3f3f3f3f;        // int型最大值(常用于表示“无穷大”)
const LL INF_LL = 0x3f3f3f3f3f3f3f3f;  // long long型最大值
const double EPS = 1e-8;           // 浮点数精度(处理浮点数比较时用)
const int MOD = 1e9 + 7;           // 常用模值(数论题、计数题常用)
const int MAXN = 2e5 + 10;         // 数组/容器最大规模(根据题目数据范围调整)

bool cmp(PII& a, PII& b) {
    return a.second < b.second;
}
int A[15][15];

bool valid(int x, int y){
    return x>=0&&x<15&&y>=0&&y<15;
}

bool check(int x, int y, bool flag){
    //横着
    int now = x;
    int k =0;
    int me = flag?1:2;
    while(valid(now,y)&&A[now][y]==me){
        k++; now++;
    }
    //多看题目!!只要是五个以上也成功!!写成了刚好五个了
    if(k>=5)return true;
    now = x; k--;
    while(valid(now,y)&&A[now][y]==me){
        k++; now--;
    }   
    if(k>=5)return true;
    k = 0; now = y;
    while(valid(x,now)&&A[x][now]==me){
        k++; now++;
    }   
    if(k>=5)return true;  
    now = y; k--;
    while(valid(x,now)&&A[x][now]==me){
        k++; now--;
    }      
    if(k>=5)return true;
    int nowy;
    k = 0; now = x; nowy = y;
    while(valid(now,nowy)&&A[now][nowy]==me){
        k++; now++;nowy++;
    }      
    if(k>=5)return true;  
    now = x; nowy = y;k--;
    while(valid(now,nowy)&&A[now][nowy]==me){
        k++; now--;nowy--;
    }  
    if(k>=5)return true; 
    k = 0; now = x; nowy = y;
    while(valid(now,nowy)&&A[now][nowy]==me){
        k++; now++;nowy--;
    }      
    if(k>=5)return true;  
    now = x; nowy = y;k--;
    while(valid(now,nowy)&&A[now][nowy]==me){
        k++; now--;nowy++;
    }  
    if(k>=5)return true;  
    return false;
}


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n; int x,y;
    cin >> n;
    for(int i = 0; i < 15;i++){
        for(int j = 0; j < 15;j++){
            A[i][j] = 0;
        }
    }
    bool flag = false;
    int w = 0;
    while(n--){
        flag = !flag;//true is A
        cin >> x >> y;
        w++;
        A[x-1][y-1] = flag?1:2;
        if(check(x-1,y-1,flag)){
            if(flag)cout<<"A"<<" ";
            else cout << "B" << " ";
            cout << w <<endl;
            return 0;
        }
    }
    cout<<"Tie" <<endl;
    return 0;
}

文件系统

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<unordered_map>
#include<set>
// 可根据题目需求补充其他头文件(如<queue>、<stack>、<map>等)
using namespace std;

// -------------------------- 常用类型别名(简化代码)--------------------------
typedef long long LL;         // 处理大整数,避免溢出
typedef vector<LL> VI;        // 一维长整型数组
typedef vector<VI> VVI;       // 二维长整型数组
typedef pair<LL, LL> PII;     // 存储二元组(如<数量, 值>、<坐标x, 坐标y>)
// 可扩展:如typedef pair<int, int> PII_int;(int型二元组)、typedef vector<PII> VPII;(二元组数组)

// -------------------------- 通用常量定义(根据题目调整值)--------------------------
const int INF = 0x3f3f3f3f;        // int型最大值(常用于表示“无穷大”)
const LL INF_LL = 0x3f3f3f3f3f3f3f3f;  // long long型最大值
const double EPS = 1e-8;           // 浮点数精度(处理浮点数比较时用)
const int MOD = 1e9 + 7;           // 常用模值(数论题、计数题常用)
const int MAXN = 2e5 + 10;         // 数组/容器最大规模(根据题目数据范围调整)

bool cmp(PII& a, PII& b) {
    return a.second < b.second;
}


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    int a;
    string s;
    cin >> n;
    vector<pair<int, string>> A;
    A.push_back({-1, "nothing"});
    for(int i = 1; i <= n; i++){
        cin >> a >> s;
        A.push_back({a,s});
    }
    vector<string> S;
    S.push_back("nothing");
    for(int i = 1; i <= n; i++){
        a = A[i].first;
        s = A[i].second;
        if(a==0){
            S.push_back("/"+s);
            continue;
        }
        S.push_back(S[a]+"/"+s);
    }    
    int sum = 0;
    for(int i = 1; i <= n; i++){
        sum += S[i].size();
    }
    cout << sum << endl;
    return 0;
}

矩阵模拟

输入1是翻转,2是行平移,3是列平移

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<unordered_map>
#include<set>
// 可根据题目需求补充其他头文件(如<queue>、<stack>、<map>等)
using namespace std;

// -------------------------- 常用类型别名(简化代码)--------------------------
typedef long long LL;         // 处理大整数,避免溢出
typedef vector<LL> VI;        // 一维长整型数组
typedef vector<VI> VVI;       // 二维长整型数组
typedef pair<LL, LL> PII;     // 存储二元组(如<数量, 值>、<坐标x, 坐标y>)
// 可扩展:如typedef pair<int, int> PII_int;(int型二元组)、typedef vector<PII> VPII;(二元组数组)

// -------------------------- 通用常量定义(根据题目调整值)--------------------------
const int INF = 0x3f3f3f3f;        // int型最大值(常用于表示“无穷大”)
const LL INF_LL = 0x3f3f3f3f3f3f3f3f;  // long long型最大值
const double EPS = 1e-8;           // 浮点数精度(处理浮点数比较时用)
const int MOD = 1e9 + 7;           // 常用模值(数论题、计数题常用)
const int MAXN = 2e5 + 10;         // 数组/容器最大规模(根据题目数据范围调整)

bool cmp(PII& a, PII& b) {
    return a.second < b.second;
}

int A[101][101] ={0};
int B[101][101] ={0};
int n;

void flip(){
    int temp;
    for (int i = 1; i <= n; i ++ ){
        for (int j = i; j <= n; j ++ ){
            temp = A[i][j];
            //cout << A[i][j] << "," << A[j][i] << endl;
            A[i][j] = A[j][i];
            A[j][i] = temp;
        }
    }
}

void checkx(int k){
    int now;
    for (int i = 1; i <= n; i ++ ){
        now = (i+k) % n;
        if(now==0)now = n;
        for (int j = 1; j <= n; j ++ ){
            B[now][j] = A[i][j];
        }
    }
    for (int i = 1; i <= n; i ++ ){
        for (int j = 1; j <= n; j ++ ){
            A[i][j] = B[i][j];
        }
    }
}

void checky(int k){
    int now;
    for (int i = 1; i <= n; i ++ ){
        now = (i+k) % n;
        if(now==0)now = n;
        for (int j = 1; j <= n; j ++ ){
            B[j][now] = A[j][i];
        }
    }
    for (int i = 1; i <= n; i ++ ){
        for (int j = 1; j <= n; j ++ ){
            A[i][j] = B[i][j];
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    for (int i = 1; i <= n; i ++ ){
        for (int j = 1; j <= n; j ++ ){
            cin >> A[i][j];
        }
    }
    int q;
    cin >> q;
    int opt,k;
    while(q--){
        cin >> opt;
        if(opt==1){
            flip();
        }
        else if(opt==2){
            cin >> k;
            checkx(k);
        }
        else if(opt==3){
            cin >> k;
            checky(k);
        }
    }
    for (int i = 1; i <= n; i ++ ){
        for (int j = 1; j <= n; j ++ ){
            cout << A[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

军训队列

把n人分为k组,差距为最大小的身高差平方,使他最小。动态规划。

再次尝试总结,这是区间dp。二层不够就三层,分为之前加上之后的,这思维就好。
主要流程:

  • 定义dp数组,特殊情况、初始化
  • 确定循环结构,确定转换方程。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<unordered_map>
#include<set>
// 可根据题目需求补充其他头文件(如<queue>、<stack>、<map>等)
using namespace std;

// -------------------------- 常用类型别名(简化代码)--------------------------
typedef long long LL;         // 处理大整数,避免溢出
typedef vector<LL> VI;        // 一维长整型数组
typedef vector<VI> VVI;       // 二维长整型数组
typedef pair<LL, LL> PII;     // 存储二元组(如<数量, 值>、<坐标x, 坐标y>)
// 可扩展:如typedef pair<int, int> PII_int;(int型二元组)、typedef vector<PII> VPII;(二元组数组)

// -------------------------- 通用常量定义(根据题目调整值)--------------------------
const int INF = 0x3f3f3f3f;        // int型最大值(常用于表示“无穷大”)
const LL INF_LL = 0x3f3f3f3f3f3f3f3f;  // long long型最大值
const double EPS = 1e-8;           // 浮点数精度(处理浮点数比较时用)
const int MOD = 1e9 + 7;           // 常用模值(数论题、计数题常用)
const int MAXN = 2e5 + 10;         // 数组/容器最大规模(根据题目数据范围调整)

bool cmp(PII& a, PII& b) {
    return a.second < b.second;
}


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n,k;
    cin >> n >> k;
    VI A(n);
    for (int i = 0; i < n; i ++ ){
        cin >> A[i];
    }
    sort(A.begin(), A.end());
    VVI dp(n+1, VI(k+1,INF_LL));
    // i代表人数,j代表队列
    //特殊情况
    if(k>=n){
        cout << 0 << endl;
        return 0;
    }
    // 初始情况,只有一个队列
    for (int i = 1; i <= n; i ++ ){
        dp[i][1] = (A[i-1]-A[0])*(A[i-1]-A[0]);
    }
    // 遍历队列数量
    for (int j = 2; j <= k; j ++ ){
        // 人数数量至少等于j不然没得分
        for (int i = j; i <= n; i ++ ){
            // 分割,用m分为前j-1组分好的,和后面新一组的,做动态规划
            for (int m = j-1; m<i; m ++ ){//是j-1因为再少不够分,小于i是没那么多人,循环就是i人最多
                LL current = dp[m][j-1] + (A[i-1]-A[m])*(A[i-1]-A[m]);//最小的就是第m个人
                dp[i][j] = min(dp[i][j],current);
            }
        }
    }
    cout << dp[n][k] << endl;
    return 0;
}

偏差

A是n长,B是m长,B是A子串,差距为k。用kmp算法解决。第一个做出的比较有难度的题目。。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
//#include<unordered_map>
#include<set>
// 可根据题目需求补充其他头文件(如<queue>、<stack>、<map>等)
using namespace std;

// -------------------------- 常用类型别名(简化代码)--------------------------
typedef long long LL;         // 处理大整数,避免溢出
typedef vector<LL> VI;        // 一维长整型数组
typedef vector<VI> VVI;       // 二维长整型数组
typedef pair<LL, LL> PII;     // 存储二元组(如<数量, 值>、<坐标x, 坐标y>)
// 可扩展:如typedef pair<int, int> PII_int;(int型二元组)、typedef vector<PII> VPII;(二元组数组)

// -------------------------- 通用常量定义(根据题目调整值)--------------------------
const int INF = 0x3f3f3f3f;        // int型最大值(常用于表示“无穷大”)
const LL INF_LL = 0x3f3f3f3f3f3f3f3f;  // long long型最大值
const double EPS = 1e-8;           // 浮点数精度(处理浮点数比较时用)
const int MOD = 1e9 + 7;           // 常用模值(数论题、计数题常用)
const int MAXN = 2e5 + 10;         // 数组/容器最大规模(根据题目数据范围调整)

bool cmp(PII& a, PII& b) {
    return a.second < b.second;
}
LL n,m;
VI A,B,suba, subb;
set<LL> res;
void kmp(){
    LL prelen = 0;
    LL i = 1;
    LL m = subb.size();
    LL n = suba.size();
    VI next(m,0);
    next[0] = 0;
    // 先为被匹配的做next数组
    while(i<m){
        if(subb[i]==subb[prelen])next[i++]=++prelen;
        else if(prelen==0)next[i++]=0;
        else prelen=next[prelen-1];
    }
    // 子串比较
    LL j = 0;
    i = 0;
    res.clear();
    while(i<n){
        if(suba[i]==subb[j])
        {i++;j++;}
        else if(j>0)
        j=next[j-1];
        else 
        i++;
        if(j==m)
        {res.insert(i-j+1);j=next[j-1];}//调整为1-base
    }
    
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    LL T;
    cin >> T;
    while(T--){
        cin >> n;
        A.clear();
        suba.clear();
        A.resize(n);
        suba.resize(n-1);
        for(int i = 0; i < n; i++){
            cin >> A[i];
        }
        for(int i = 0; i < n-1; i++){
            suba[i] = A[i+1]-A[i];
        }//从0存储
        cin >> m;
        if(m==1){
            res.clear();
            B.clear();
            B.resize(m);
            cin >> B[0];
            for(int i = 1; i <= n; i++)res.insert(i);
        }else{
            B.clear();
            subb.clear();
            B.resize(m);
            subb.resize(m-1);
            for(int i = 0; i < m; i++){
                cin >> B[i];
            }      
            for(int i = 0; i < m-1; i++){
                subb[i] = B[i+1]-B[i];
            }//从0存储
            kmp();
        }
        /*for(auto x:suba)cout << x << " ";
        cout << endl;
        for(auto x:subb)cout << x << " ";
        cout << endl; 
        for(auto x:res)cout << x << " ";
        cout << endl;  
        cout << endl;*/

        // 问题1
        set<LL>kpos; LL k;
        LL mine = INF_LL;
        for(auto x:res){
            k = B[0] - A[x-1];
            kpos.insert(k);
            mine = min(abs(k),mine);// 问题2
        }
        cout << kpos.size() << " ";
        // 问题2
        if(mine==INF_LL)mine = 0;
        cout << mine << " ";
        // 问题3
        cout << res.size() << " ";
        // 问题4 5
        if(res.empty()){cout << 0 <<" " <<0 << endl;continue;}
        cout << *res.begin() << " " << *res.rbegin() << endl;      
    }
    return 0;
}

面试

给出 n人至少m人一队,最高最低差距不能大于k。
我的做法错误了,但是有些结构可以学习:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<unordered_map>
#include<set>
// 可根据题目需求补充其他头文件(如<queue>、<stack>、<map>等)
using namespace std;

// -------------------------- 常用类型别名(简化代码)--------------------------
typedef long long LL;         // 处理大整数,避免溢出
typedef vector<LL> VI;        // 一维长整型数组
typedef vector<VI> VVI;       // 二维长整型数组
typedef pair<LL, LL> PII;     // 存储二元组(如<数量, 值>、<坐标x, 坐标y>)
// 可扩展:如typedef pair<int, int> PII_int;(int型二元组)、typedef vector<PII> VPII;(二元组数组)

// -------------------------- 通用常量定义(根据题目调整值)--------------------------
const int INF = 0x3f3f3f3f;        // int型最大值(常用于表示“无穷大”)
const LL INF_LL = 0x3f3f3f3f3f3f3f3f;  // long long型最大值
const double EPS = 1e-8;           // 浮点数精度(处理浮点数比较时用)
const int MOD = 1e9 + 7;           // 常用模值(数论题、计数题常用)
const int MAXN = 2e5 + 10;         // 数组/容器最大规模(根据题目数据范围调整)

bool cmp(PII& a, PII& b) {
    return a.second < b.second;
}
/* 访问集合的方法
        auto rit = s.rbegin();/begin();
        advance(rit, 1); // 移动1步(等价于 ++rit)
*/

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n,m,k;
    cin >> n>>m>>k;
    VI A(n);
    for (int i = 0; i < n; i ++ ){
        cin >> A[i];
    }
    // 朴素的贪心:把最小的尽量去掉,最大的尽量去掉,维护他是m个,再求差值
    // 集合可以直接做到最大 最小的访问和插入与删除
    // map有序的哈希表
    // multiset可重复的集合
    multiset<LL> S;
    multiset<LL> shadow;
    LL f,b,fl,bl;
    unordered_map<LL,LL> U;
    for (int i = 0; i < n; i ++ ){
        if(S.find(A[i])!=S.end()){
            U[A[i]] += 1;
            if(k==0&&U[A[i]]==m-1){
                cout << i + 1 << endl;
                return 0;
            }
        }
        S.insert(A[i]);
        if(i >= m - 1 && k != 0){
            shadow = S;
            while(shadow.size()>=m){
                auto fit = shadow.rbegin();
                auto bit = shadow.begin();
                f = *fit;
                b = *bit;
                if(f-b<=k){
                    cout << i + 1<< endl; return 0;
                }
                advance(fit, 1);
                advance(bit, 1);
                fl = *fit;
                bl = *bit;
                if(fl - b < f - bl){
                    auto it = shadow.find(f);//删除一个multiset而不是全部
                    shadow.erase(it);
                }else{
                    auto it = shadow.find(b);
                    shadow.erase(it);
                }
            }
        }
    }
    cout << "impossible" << endl;
    return 0;
}

正确做法,利用有序性,检查所有连续 m 个元素:

#include<iostream>
#include<algorithm>
#include<vector>
#include<unordered_map>
using namespace std;

typedef long long LL;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int n, m, k;
    cin >> n >> m >> k;
    vector<LL> heights(n);
    for (int i = 0; i < n; ++i) {
        cin >> heights[i];
    }

    // 1. 特殊处理k=0:需要m个相同身高
    if (k == 0) {
        unordered_map<LL, int> count;
        for (int i = 0; i < n; ++i) {
            if (++count[heights[i]] >= m) {
                cout << i + 1 << endl;
                return 0;
            }
        }
        cout << "impossible" << endl;
        return 0;
    }

    // 2. 维护有序数组:存储已面试的所有身高(始终升序)
    vector<LL> sorted_heights;
    for (int i = 0; i < n; ++i) {
        // 插入当前身高,保持数组有序(lower_bound找插入位置)
        auto insert_pos = lower_bound(sorted_heights.begin(), sorted_heights.end(), heights[i]);
        sorted_heights.insert(insert_pos, heights[i]);

        // 3. 当元素数≥m时,检查所有连续m个元素的身高差
        if (sorted_heights.size() >= m) {
            // 遍历所有可能的起始位置j,检查j到j+m-1的连续m个元素
            for (int j = 0; j <= sorted_heights.size() - m; ++j) {
                LL min_h = sorted_heights[j];
                LL max_h = sorted_heights[j + m - 1];
                if (max_h - min_h <= k) {
                    cout << i + 1 << endl; // 面试人数是i+1(0-based转1-based)
                    return 0;
                }
            }
        }
    }

    // 4. 遍历完所有面试者仍无有效组合
    cout << "impossible" << endl;
    return 0;
}

售货机

给出n个 a 价格 b可能买到的另一个 p 买到a的概率,人来买随机买一个口,如果没买到x就买买错的那个口,直到买到或者买到空的了。求期望。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<unordered_map>
#include<set>
// 可根据题目需求补充其他头文件(如<queue>、<stack>、<map>等)
using namespace std;

// -------------------------- 常用类型别名(简化代码)--------------------------
typedef int LL;         // 处理大整数,避免溢出
typedef vector<LL> VI;        // 一维长整型数组
typedef vector<VI> VVI;       // 二维长整型数组
typedef pair<LL, LL> PII;     // 存储二元组(如<数量, 值>、<坐标x, 坐标y>)
// 可扩展:如typedef pair<int, int> PII_int;(int型二元组)、typedef vector<PII> VPII;(二元组数组)

// -------------------------- 通用常量定义(根据题目调整值)--------------------------
const int INF = 0x3f3f3f3f;        // int型最大值(常用于表示“无穷大”)
//const LL INF_LL = 0x3f3f3f3f3f3f3f3f;  // long long型最大值
const double EPS = 1e-8;           // 浮点数精度(处理浮点数比较时用)
const int MOD = 1e9 + 7;           // 常用模值(数论题、计数题常用)
const int MAXN = 2e5 + 10;         // 数组/容器最大规模(根据题目数据范围调整)

bool cmp(PII& a, PII& b) {
    return a.second < b.second;
}

struct me{
    LL a;
    LL b;
    double pa;
    double pb;
};

struct st{
    LL start;
    LL idx;
    double p;
    LL pri;
    bool flag;// 为0是自己,为1是另一个
};

vector<bool> used,tempused;
vector<st> path;
LL n,x;
vector<me> A;
double allp = 1;
LL nexti;
double nowp = 1;
double ans = 0;
double pp = 0;

void check(){
    if(path.empty()){
        nexti = -1;
    }else{
        nexti = path.back().idx;//访问最后一个元素
    }
    if(!path.empty()){
        auto nowget = path.back();//访问最后一个元素
        if(nowget.idx == x){
            pp = allp;
            double sum = 0;
            fill(tempused.begin(), tempused.end(), false);
            for(auto ok : path){
                sum += ok.pri;
                // cout <<"{" << ok.start << ", " << ok.idx << ", " << ok.p << ", " << ok.pri << "} ";
                if(ok.flag){
                    if(tempused[ok.start]){
                        pp = pp;
                    }else{
                        pp = pp * ok.p;
                    }
                }else{
                    if(tempused[A[ok.idx].b]){
                        pp = pp;
                    }else{
                        pp = pp * ok.p;
                    }                    
                }
                tempused[ok.idx] = true;
            }
            // cout << pp <<", "<< sum << endl;
            ans += pp * sum;
            nexti =-1;
            return;
        }
        int i = nexti;
               if(!used[i]){//买到自己
                path.push_back({i, i, A[i].pa, A[i].a, 0});
                used[i] = true;
                check();
                used[i] = false;
                path.pop_back();
            }
            if(!used[A[i].b]){//买到另一个
                path.push_back({i, A[i].b, A[i].pb, A[i].a, 1});
                used[A[i].b] = true;
                check();
                used[A[i].b] = false;
                path.pop_back();            
            }
            if(used[A[i].b]&&used[i]){// 漏了硬买一次。。。不然就做出来了
                // 都买不到了, 那么硬买一次,然后 ,直接计算
                    pp = allp;
                    double sum = A[i].a;
                    fill(tempused.begin(), tempused.end(), false);
                    for(auto ok : path){
                        sum += ok.pri;
                        // cout <<"{" << ok.start << ", " << ok.idx << ", " << ok.p << ", " << ok.pri << "} ";
                        if(ok.flag){
                            if(tempused[ok.start]){
                                pp = pp;
                            }else{
                                pp = pp * ok.p;
                            }
                        }else{
                            if(tempused[A[ok.idx].b]){
                                pp = pp;
                            }else{
                                pp = pp * ok.p;
                            }                    
                        }
                        tempused[ok.idx] = true;
                    }
                    // cout << pp <<", "<< sum << endl;
                    ans += pp * sum;
                    nexti = -1;
                    return;                        
            }
    }else{
        for(int i = 1; i <= n; i ++){
                path.push_back({i, i, A[i].pa, A[i].a, 0});
                used[i] = true;
                check();
                used[i] = false;
                path.pop_back();

                path.push_back({i, A[i].b, A[i].pb, A[i].a, 1});
                used[A[i].b] = true;
                check();
                used[A[i].b] = false;
                path.pop_back();            
        }
    }
}
    

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> x;
    A.resize(n+1);
    used.resize(n+1, false);
    tempused.resize(n+1, false);
    for(int i = 1; i <= n; i++){
        cin >> A[i].a >> A[i].b >> A[i].pa;
        A[i].pb = 1 - A[i].pa;
    }
    allp /= n;
    check();
    printf("%.6f", ans);
    return 0;
}

公司

输入全部员工工资和一堆PII,代表x知道y的工资,如果知道的工资平均大于他的工资,就要离职。记录要离职的人数量。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<unordered_map>
#include<set>
// 可根据题目需求补充其他头文件(如<queue>、<stack>、<map>等)
using namespace std;

// -------------------------- 常用类型别名(简化代码)--------------------------
typedef long long LL;         // 处理大整数,避免溢出
typedef vector<LL> VI;        // 一维长整型数组
typedef vector<VI> VVI;       // 二维长整型数组
typedef pair<LL, LL> PII;     // 存储二元组(如<数量, 值>、<坐标x, 坐标y>)
// 可扩展:如typedef pair<int, int> PII_int;(int型二元组)、typedef vector<PII> VPII;(二元组数组)

// -------------------------- 通用常量定义(根据题目调整值)--------------------------
const int INF = 0x3f3f3f3f;        // int型最大值(常用于表示“无穷大”)
const LL INF_LL = 0x3f3f3f3f3f3f3f3f;  // long long型最大值
const double EPS = 1e-8;           // 浮点数精度(处理浮点数比较时用)
const int MOD = 1e9 + 7;           // 常用模值(数论题、计数题常用)
const int MAXN = 2e5 + 10;         // 数组/容器最大规模(根据题目数据范围调整)

bool cmp(PII& a, PII& b) {
    return a.second < b.second;
}


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    LL n, m;
    cin >> n >> m;
    vector<double> A(n+1, 0); // 员工自己的工资
    vector<double> K(n+1, -1); // 知道的平均数
    VI N(n+1, 0); // 知道的数量(辅助快速计算平均数)
    for(int i = 1; i <= n; i++){
        cin >> A[i];
    }
    LL a,b;
    for(int i = 1; i <= m; i++){
        cin >> a >> b;
        K[a] = (K[a] * N[a] + A[b]) / (N[a] + 1);
        N[a] ++;
    } 
    LL ans=0;
    for(int i = 1; i <= n; i++){
        if(K[i]==-1)continue;
        if(A[i] < K[i])ans++;
    }       
    cout << ans << endl;
    return 0;
}

擂台赛

基数比较小,直接8 4 2写函数,然后处理。其中比较出问题的是four数组索引出错后面改了,然后就是n=8的时候的除数不知道是多少还是看输出才写对了。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<unordered_map>
#include<set>
// 可根据题目需求补充其他头文件(如<queue>、<stack>、<map>等)
using namespace std;

// -------------------------- 常用类型别名(简化代码)--------------------------
typedef long long LL;         // 处理大整数,避免溢出
typedef vector<LL> VI;        // 一维长整型数组
typedef vector<VI> VVI;       // 二维长整型数组
typedef pair<LL, LL> PII;     // 存储二元组(如<数量, 值>、<坐标x, 坐标y>)
// 可扩展:如typedef pair<int, int> PII_int;(int型二元组)、typedef vector<PII> VPII;(二元组数组)

// -------------------------- 通用常量定义(根据题目调整值)--------------------------
const int INF = 0x3f3f3f3f;        // int型最大值(常用于表示“无穷大”)
const LL INF_LL = 0x3f3f3f3f3f3f3f3f;  // long long型最大值
const double EPS = 1e-8;           // 浮点数精度(处理浮点数比较时用)
const int MOD = 1e9 + 7;           // 常用模值(数论题、计数题常用)
const int MAXN = 2e5 + 10;         // 数组/容器最大规模(根据题目数据范围调整)

bool cmp(PII& a, PII& b) {
    return a.second < b.second;
}

VI pathe;
VI pathf;
LL four[4] = {1,2,3,4};
LL two[2] = {0}; 
LL ans = 0;
LL n;
LL A[9][9] = {0};
vector<bool> used(9, false);
vector<bool> usedf(5, false);
VI list;

void workfour(bool flag){
    if(!flag){// 如果不是起源要先处理pathe  
        int j = 0;
        for(int i = 0; i < 8; i+=2){
            if(A[pathe[i]][pathe[i+1]]==1){
                four[j++] = pathe[i];//打比赛,谁赢了,留下谁,进入下一关
            }else{
                four[j++] = pathe[i+1];
            }
        }
    }
    if(pathf.size()==4){
        // 达到4个直接决出胜负
        int j = 0;
        for (int i = 0; i < 4; i+=2)
        {
            if(A[pathf[i]][pathf[i+1]]==1){
                two[j++] = pathf[i];
            }else{
                two[j++] = pathf[i+1];
            }
        }
        if(A[two[0]][two[1]]==1){
            if(two[0]==1){
                ans++;
                // 记录一下
                for (int i = 0; i < 4; i++)
                {
                    list.push_back(pathf[i]);
                }
            
            }
        }
        return;
    }
    for(int i = 0; i <= 3; i++){
        if(!usedf[i]){
            pathf.push_back(four[i]);
            usedf[i] = true;
            workfour(true);
            usedf[i] = false;
            pathf.pop_back();            
        }
    }
}

void workeight(){// 比赛中/正在处理的人数
    if(pathe.size()==8){
        //for(auto x: pathe) cout << x << " ";
        //cout << endl;
        workfour(false);
        return;
    }
    for(int i = 1; i <= 8; i++){
        if(!used[i]){
            pathe.push_back(i);
            used[i] = true;
            workeight();
            used[i] = false;
            pathe.pop_back();            
        }
    }   
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            cin >> A[i][j];
        }
    }
    if(n == 8){
        workeight();
        ans /= 192;
    }else if(n == 4){
        workfour(true);
        ans /= 2;
    }else if(n==2){
        if(A[1][2]==1){
            ans = 1;
        }
    }
    cout << ans <<endl;
    /*int j = 0;
    while(j<list.size()){
        if(j%4==0)cout << endl;
        cout << "(" << list[j] << ", " << list[j+1] << ")" << " ";
        j+=2;
    }*/

    return 0;
}

nextper升级版

直接快了超级多

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<unordered_map>
#include<set>
// 可根据题目需求补充其他头文件(如<queue>、<stack>、<map>等)
using namespace std;

// -------------------------- 常用类型别名(简化代码)--------------------------
typedef long long LL;         // 处理大整数,避免溢出
typedef vector<LL> VI;        // 一维长整型数组
typedef vector<VI> VVI;       // 二维长整型数组
typedef pair<LL, LL> PII;     // 存储二元组(如<数量, 值>、<坐标x, 坐标y>)
// 可扩展:如typedef pair<int, int> PII_int;(int型二元组)、typedef vector<PII> VPII;(二元组数组)

// -------------------------- 通用常量定义(根据题目调整值)--------------------------
const int INF = 0x3f3f3f3f;        // int型最大值(常用于表示“无穷大”)
const LL INF_LL = 0x3f3f3f3f3f3f3f3f;  // long long型最大值
const double EPS = 1e-8;           // 浮点数精度(处理浮点数比较时用)
const int MOD = 1e9 + 7;           // 常用模值(数论题、计数题常用)
const int MAXN = 2e5 + 10;         // 数组/容器最大规模(根据题目数据范围调整)

bool cmp(PII& a, PII& b) {
    return a.second < b.second;
}

VI pathe={1,2,3,4,5,6,7,8};
VI pathf={1,2,3,4};
LL two[2] = {0}; 
LL ans = 0;
LL n;
LL A[9][9] = {0};
vector<bool> used(9, false);
vector<bool> usedf(5, false);
VI list;

void workfour(bool flag){
    if(!flag){// 如果不是起源要先处理pathe  
        int j = 0;
        for(int i = 0; i < 8; i+=2){
            if(A[pathe[i]][pathe[i+1]]==1){
                pathf[j++] = pathe[i];//打比赛,谁赢了,留下谁,进入下一关
            }else{
                pathf[j++] = pathe[i+1];
            }
        }
    }
    sort(pathf.begin(),pathf.end());
    do{
        int j = 0;
        for (int i = 0; i < 4; i+=2)
        {
            if(A[pathf[i]][pathf[i+1]]==1){
                two[j++] = pathf[i];
            }else{
                two[j++] = pathf[i+1];
            }
        }
        if(A[two[0]][two[1]]==1){
            if(two[0]==1){
                ans++;
            }
        }else{
            if(two[1]==1){
                ans++;
            }
        }
    }while(next_permutation(pathf.begin(),pathf.end()));//用之前要排序的
}

void workeight(){// 比赛中/正在处理的人数
    do{
        workfour(false);
    }while(next_permutation(pathe.begin(),pathe.end()));
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            cin >> A[i][j];
        }
    }
    if(n == 8){
        workeight();
        ans /= 384;//全排列4的阶乘24乘以2*2*2*2的位置互换
    }else if(n == 4){
        workfour(true);
        ans /= 4; //全排列2的阶乘乘以2的变换
    }else if(n==2){
        if(A[1][2]==1){
            ans = 1;
        }
    }
    cout << ans <<endl;
    return 0;
}

有点ez了,就是需要幻想一下

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<unordered_map>
#include<set>
#include<cstring>
#include<cstdio>
// 可根据题目需求补充其他头文件(如<queue>、<stack>、<map>等)
using namespace std;

// -------------------------- 常用类型别名(简化代码)--------------------------
typedef long long LL;         // 处理大整数,避免溢出
typedef vector<LL> VI;        // 一维长整型数组
typedef vector<VI> VVI;       // 二维长整型数组
typedef pair<LL, LL> PII;     // 存储二元组(如<数量, 值>、<坐标x, 坐标y>)
// 可扩展:如typedef pair<int, int> PII_int;(int型二元组)、typedef vector<PII> VPII;(二元组数组)

// -------------------------- 通用常量定义(根据题目调整值)--------------------------
const int INF = 0x3f3f3f3f;        // int型最大值(常用于表示“无穷大”)
const LL INF_LL = 0x3f3f3f3f3f3f3f3f;  // long long型最大值
const double EPS = 1e-8;           // 浮点数精度(处理浮点数比较时用)
const int MOD = 1e9 + 7;           // 常用模值(数论题、计数题常用)
const int MAXN = 2e5 + 10;         // 数组/容器最大规模(根据题目数据范围调整)

bool cmp(PII& a, PII& b) {
    return a.second < b.second;
}
const int BUF_SIZE = 1 << 20;
char buf[BUF_SIZE];
int buf_ptr=0;
int buf_len=0;

inline char my_getc(){
    if(buf_ptr>=buf_len){
        buf_len = fread(buf, 1, BUF_SIZE, stdin);
        buf_ptr=0;
        if(buf_len==0)return EOF;
    }
    return buf[buf_ptr++];
}

inline long long r(){
    LL x =0;
    int sign = 1;
    char ch = my_getc();
    while(ch==' '|| ch == '\n'|| ch == '\r'|| ch == '\t'){
        ch = my_getc();
    }
    if(ch == '-'){
        sign = -1;
        ch = my_getc();
    }
    while(ch>='0'&&ch<='9'){
        x = x*10+(ch - '0' );
        ch = my_getc();
    }
    return x*sign;
}

LL n;
VVI H;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    n = r();
    H.resize(n+1, VI(n+1,0));
    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= n; j ++){
            H[i][j] = r();
        }        
    }
    VI L(n+1,0), R(n+1,0), U(n+1,0), D(n+1,0);
    //先处理L
    LL maxme=0;
    for(int i = 1; i <= n; i ++){
        if(H[i][1] == n){
            L[i]=1;
            continue;
        }
        maxme = 0;
        for(int j = 1; j <= n; j ++){
            if(maxme==n)break;
            if(H[i][j]>maxme){
                L[i]++;
                maxme = H[i][j];
            }
        }        
    }    
    for(int i = 1; i <= n; i ++){
        if(H[i][n] == n){
            R[i]=1;
            continue;
        }
        maxme = 0;
        for(int j = n; j >= 1; j --){
            if(maxme==n)break;
            if(H[i][j]>maxme){
                R[i]++;
                maxme = H[i][j];
            }
        }        
    } 
    for(int i = 1; i <= n; i ++){
        if(H[1][i] == n){
            U[i]=1;
            continue;
        }
        maxme = 0;
        for(int j = 1; j <= n; j ++){
            if(maxme==n)break;
            if(H[j][i]>maxme){
                U[i]++;
                maxme = H[j][i];
            }
        }        
    }   
    for(int i = 1; i <= n; i ++){
        if(H[n][i] == n){
            D[i]=1;
            continue;
        }
        maxme = 0;
        for(int j = n; j >= 1; j--){
            if(maxme==n)break;
            if(H[j][i]>maxme){
                D[i]++;
                maxme = H[j][i];
            }
        }        
    }     
    for(int i = 1; i<=n; i++){
        cout << L[i] << " " << R[i] << " " << U[i] << " " << D[i] << endl;
    }
    return 0;
}

树上计数

好像自己开创了一个独特的BFS方法。。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<unordered_map>
#include<set>
// 可根据题目需求补充其他头文件(如<queue>、<stack>、<map>等)
using namespace std;

// -------------------------- 常用类型别名(简化代码)--------------------------
typedef long long LL;         // 处理大整数,避免溢出
typedef vector<LL> VI;        // 一维长整型数组
typedef vector<VI> VVI;       // 二维长整型数组
typedef pair<LL, LL> PII;     // 存储二元组(如<数量, 值>、<坐标x, 坐标y>)
// 可扩展:如typedef pair<int, int> PII_int;(int型二元组)、typedef vector<PII> VPII;(二元组数组)

// -------------------------- 通用常量定义(根据题目调整值)--------------------------
const int INF = 0x3f3f3f3f;        // int型最大值(常用于表示“无穷大”)
const LL INF_LL = 0x3f3f3f3f3f3f3f3f;  // long long型最大值
const double EPS = 1e-8;           // 浮点数精度(处理浮点数比较时用)
const int MOD = 1e9 + 7;           // 常用模值(数论题、计数题常用)
const int MAXN = 2e5 + 10;         // 数组/容器最大规模(根据题目数据范围调整)

bool cmp(PII& a, PII& b) {
    return a.second < b.second;
}


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    LL n,l,r;
    cin >> n >> l >> r;
    // 子树及其节点
    VVI T(n+1); LL pa;
    for(int i = 2; i <= n; i++){
        cin >> pa;
        T[pa].push_back(i);
    }
    VI CH(n+1,1);//维护一个子树数量数组,方便后续取用
    // 倒着记录
    // 必须先摸清楚他们的顺序才行
    // 从1出发
    VVI G;
    VI last = {1};
    VI now = {1};
    LL count = 0;
    while(count < n){//处理了n个才算结束
        G.push_back(now);
        count += now.size();
        last = now;
        now.clear();
        for(auto x : last){
            for(auto y : T[x]){
                now.push_back(y);//把上一层的全部的下一层放入now
            }
        }
    }
    //得到了层级,开始从底下往上获取ch
    // 初始化最后一层都是1,好像已经弄过了
    for(int i = G.size()-2; i>=0; i--){
        for(auto x : G[i]){// 每一层的节点
            // 每一层的节点的下一个
            for(auto y : T[x]){
                CH[x] += CH[y];
            }
        }
    }
    // 得到之后遍历计算就行
    LL ans = 0;
    for(int i = 1; i <= n; i++){
        if(CH[i]>=l&&CH[i]<=r)ans++;
    }
    cout << ans << endl;
    return 0;
}

毕业照

ABCDE五个人。
给出限制m,里面要求某个人和某个人不能在一起或者必须在一起,求可以的排列个数。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<unordered_map>
#include<set>
// 可根据题目需求补充其他头文件(如<queue>、<stack>、<map>等)
using namespace std;

// -------------------------- 常用类型别名(简化代码)--------------------------
typedef long long LL;         // 处理大整数,避免溢出
typedef vector<LL> VI;        // 一维长整型数组
typedef vector<VI> VVI;       // 二维长整型数组
typedef pair<LL, LL> PII;     // 存储二元组(如<数量, 值>、<坐标x, 坐标y>)
// 可扩展:如typedef pair<int, int> PII_int;(int型二元组)、typedef vector<PII> VPII;(二元组数组)

// -------------------------- 通用常量定义(根据题目调整值)--------------------------
const int INF = 0x3f3f3f3f;        // int型最大值(常用于表示“无穷大”)
const LL INF_LL = 0x3f3f3f3f3f3f3f3f;  // long long型最大值
const double EPS = 1e-8;           // 浮点数精度(处理浮点数比较时用)
const int MOD = 1e9 + 7;           // 常用模值(数论题、计数题常用)
const int MAXN = 2e5 + 10;         // 数组/容器最大规模(根据题目数据范围调整)

bool cmp(PII& a, PII& b) {
    return a.second < b.second;
}

LL ans = 0;
vector<char> S = {'A','B','C','D','E'};
vector<pair<char,char>> no;
vector<pair<char,char>> yes;
char u,v;
// 做一个预处理直接记住身边是谁然后就不用到处找了,减去0x40就是1-base的索引
vector<vector<char>> pre;
void check(){
    // 预处理我身边是谁
    pre.clear();
    pre.resize(6);
    for(int i = 0; i < 5; i++){
        if(i==0){
            pre[S[i]-0x40].push_back(S[i+1]);
            continue;
        }else if(i==4){
            pre[S[i]-0x40].push_back(S[i-1]);
            continue;            
        }else{
            pre[S[i]-0x40].push_back(S[i-1]);
            pre[S[i]-0x40].push_back(S[i+1]);
        }
    }
    bool flag=false;
    for(auto x: yes){
        u = x.first;
        v = x.second;
        flag = false;
        for(auto y:pre[u-0x40]){
            if(v==y){//如果遇到一样的标记为true跳出
                flag = true;
                break;
            }
        }
        if(!flag)return;//不是true就返回      
    }

    for(auto x: no){
        u = x.first;
        v = x.second;
        for(auto y:pre[u-0x40]){
            if(v==y)return;//不要让一起的遇到一起了就直接返回
        }
    }
    ans++;//经历磨难才可以++
    return;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    LL m;
    cin >> m;
    int op;
    char a,b;
    while(m--){
        cin >> op >> a >> b;
        if(op==1){
            yes.push_back({a,b});
        }else if(op==2){
            no.push_back({a,b});
        }
    }
    do{
        check();
    }while(next_permutation(S.begin(),S.end()));
    cout << ans << endl;
    return 0;
}

prime

输入一个数字,加数字(第一个不能是0)让他变为质数

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<unordered_map>
#include<set>
// 可根据题目需求补充其他头文件(如<queue>、<stack>、<map>等)
using namespace std;

// -------------------------- 常用类型别名(简化代码)--------------------------
typedef long long LL;         // 处理大整数,避免溢出
typedef vector<LL> VI;        // 一维长整型数组
typedef vector<VI> VVI;       // 二维长整型数组
typedef pair<LL, LL> PII;     // 存储二元组(如<数量, 值>、<坐标x, 坐标y>)
// 可扩展:如typedef pair<int, int> PII_int;(int型二元组)、typedef vector<PII> VPII;(二元组数组)

// -------------------------- 通用常量定义(根据题目调整值)--------------------------
const int INF = 0x3f3f3f3f;        // int型最大值(常用于表示“无穷大”)
const LL INF_LL = 0x3f3f3f3f3f3f3f3f;  // long long型最大值
const double EPS = 1e-8;           // 浮点数精度(处理浮点数比较时用)
const int MOD = 1e9 + 7;           // 常用模值(数论题、计数题常用)
const int MAXN = 2e5 + 10;         // 数组/容器最大规模(根据题目数据范围调整)

bool cmp(PII& a, PII& b) {
    return a.second < b.second;
}

bool isp(int x){
    if(x<2)return false;
    for (int i = 2; i <= x/i; i ++ ){
        if(x%i==0){
            return false;
        }
    }
    return true;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t,x;
    t = 1;
    int now;
    while(t--){
        cin >> x;
        now = x;
        while(true){
            now++;
            if(now/10==x){
                if(isp(now)){
                    cout <<  now << endl;
                    break;
                }
            }else if(now/100==x){
                if((now/10)%10!=0&&isp(now)){
                    cout <<  now << endl;
                    break;
                }
            }
        }
    }
    return 0;
}
posted @ 2025-09-03 21:26  .N1nEmAn  阅读(112)  评论(0)    收藏  举报