第五次作业题解

第五次作业题解

P3156 【深基15.例1】询问学号 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

\(vector\)的输入

  • for (auto &i : a) cin >> i;

  • for(int i = 0;i < n;i ++) cin >> a[i];

  • for(int i = 0;i < n;i ++){

    cin >> x;

    a.push_back(x);

    }
    前两种是\(vector\)大小确定的情况下才可以那样写,否则就要按照第三种写法

#include <bits/stdc++.h>

using namespace std;

int main() {

    int n,m;
    cin >> n >> m;
    vector<int> a(n);
    for(auto &i : a) cin >> i;//也可以for(int i = 0;i < n;i ++) cin >> a[i];
    while(m--){
        int x;
        cin >> x;
        x--;
        cout << a[x] << endl;
    }

    return 0;
}

[ABC088B] Card Game for Two - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 10;

int main() {

    int n,m;
    cin >> n;
    int a = 0, b = 0;
    vector<int> s(n);
    for(int i = 0;i < n;i ++)
        cin >> s[i];
    sort(s.begin(), s.end(), greater<>());//从大到小排序
    for(int i = 0;i < n;i += 2)//贪心思想,因为交叉取最大的数,所以最先选的人肯定选偶数下标
        a += s[i];
    for(int i = 1;i < n;i += 2)
        b += s[i];
    cout << a - b << endl;

    return 0;
}

B3630 排队顺序 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 10;

int main() {

    int n,m;
    cin >> n;
    vector<int> a(n + 1);
    for(int i = 1;i <= n;i ++){
        cin >> m;
        a[i] = m;
    }

    int k;
    cin >> k;
    while(k != 0){
        cout << k << ' ';
        k = a[k];//每次令k等于后面那个,链表思想
    }

    return 0;
}

B3631 单向链表 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 10;

int main() {

    int n,m;
    vector<int> next(N);
    cin >> n;
    while(n--){
        int op;
        int x,y;
        cin >> op >> x;
        switch (op) {
            case 1:
                cin >> y;
                next[y] = next[x];
                next[x] = y;//链表插入,让x的下一个等于y,y的下一个等于x的下一个
                break;
            case 2:
                cout << next[x] << endl;
                break;
            case 3:
                next[x] = next[next[x]];//链表删除,x的下一个等于(x的下一个)的下一个,会有点绕
        }
    }

    return 0;
}

B3765 [语言月赛202305] 超链接 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 10;

bool vis[N];//标记哪些网页访问过
int main() {

    int n,m;
    cin >> n;
    vector<int> g[n + 1];
    for (int i = 1; i <= n; ++i) {
        cin >> m;
        int x;
        while(m--){
            cin >> x;
            g[i].push_back(x);//g是个二维数组,它的列是不确定的,不能直接g[i][x];
        }
    }

    int ans = 1;
    vis[1] = 1;
    for(auto i : g[1]){//只是点击两次,所以就去循环两次即可
        if(!vis[i]){//如果没有访问过,就标记一下,答案+1
            vis[i] = 1;
            ans++;
        }
        for(auto j : g[i])
            if(!vis[j]){
                vis[j] = 1;//同上
                ans++;
            }
    }
    
    cout << ans << endl;

    return 0;
}

B3614 【模板】栈 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <bits/stdc++.h>

using namespace std;

typedef unsigned long long ull;//这道题常数很大,不开无符号长整形即unsigned long long过不了

int main() {

    ull n,m;
    cin >> n;
    while(n--){
        cin >> m;
        stack<ull> Q;
        string s;
        ull x;
        while(m--){
            cin >> s;
            if(s == "push"){
                cin >> x;
                Q.push(x);
            }else if(s == "size")
                cout << Q.size() << endl;
            else if(s == "pop"){
                if(Q.empty())
                    cout << "Empty" << endl;
                else
                    Q.pop();
            }else if(s == "query"){
                if(Q.empty())
                    cout << "Anguei!" << endl;
                else
                    cout << Q.top() << endl;
            }
        }
    }

    return 0;
}

P1449 后缀表达式 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <bits/stdc++.h>

using namespace std;

int main() {

    string s;
    cin >> s;
    stack<int> Q;

    for(int i = 0;i < s.size();i ++){
        if(s[i] == '@') break;

        int num = 0;
        while(s[i] >= '0' && s[i] <= '9'){
            num = num * 10 + (s[i] - '0');
            i++;
        }

        if(s[i] == '.' || s[i] == '@') {
            Q.push(num);
            continue;
        }

        if(Q.size() > 1){
            int m1 = Q.top();
            Q.pop();
            int m2 = Q.top();
            Q.pop();
            int ans;

            switch (s[i]) {
                case  '-':
                    ans = m2 - m1;
                    break;
                case '+':
                    ans = m2 + m1;
                    break;
                case '*':
                    ans = m2 * m1;
                    break;
                default:
                    ans = m2 / m1;
            }
            Q.push(ans);
        }

    }
    cout << Q.top() << endl;

    return 0;
}

P1241 括号序列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <bits/stdc++.h>

using namespace std;

int main() {

    string s;
    cin >> s;
    stack<int> Q;
    bool v[110] = {0};
    for(int i = 0;i < s.size();i ++){
        if(Q.size()){//判断的时候Q.size()等价于!Q.empty()
            if(s[i] == ')' && s[Q.top()] == '(' && Q.size()|| s[i] == ']' && s[Q.top()] == '[' && Q.size()) {
                v[Q.top()] = v[i] = 1;
                Q.pop();
            }
        }
        if(s[i] == '(' || s[i] == '[')
            Q.push(i);
    }

    for(int i = 0;i < s.size();i ++){
        if(v[i])
            cout << s[i];
        else{
            if(s[i] == '(' || s[i] == ')')
                cout << "()";
            else
                cout << "[]";
        }
    }

    return 0;
}

P1739 表达式括号匹配 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <bits/stdc++.h>

using namespace std;

bool v[1000];
int main() {

    string s;
    cin >> s;
    stack<char> st;
    for(auto i : s){
        if(i == ')'){
            if(st.empty()){
                cout << "NO" << endl;
                return 0;
            }
            else
                st.pop();
        }else if(i == '(')
            st.push(i);
    }
    cout << (st.empty() ? "YES" : "NO") << endl;

    return 0;
}

B3616 【模板】队列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <bits/stdc++.h>

using namespace std;

int main() {

    int n,m;
    cin >> n;
    queue<int> Q;
    while(n--){
        int op ;
        cin >> op;
        switch (op) {
            case 1:
                int x;
                cin >> x;
                Q.push(x);
                break;
            case 2:
                if(Q.empty())
                    cout  << "ERR_CANNOT_POP" << endl;
                else
                    Q.pop();
                break;
            case 3:
                if(Q.empty())
                    cout << "ERR_CANNOT_QUERY" << endl;
                else
                    cout << Q.front() << endl;
                break;
            default:
                cout << Q.size() << endl;
        }
    }

    return 0;
}

P1996 约瑟夫问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <bits/stdc++.h>

using namespace std;

int main() {

    int n,m;
    cin >> n >> m;
    queue<int> Q;

    for(int i = 1;i <= n;i ++){
        Q.push(i);
    }

    int cnt = 0;
    while(Q.size()){
        int u = Q.front();
        Q.pop();

        cnt++;
        if(cnt % m == 0){
            cout << u << ' ';
        }else
            Q.push(u);//重新入队
    }

    return 0;
}

P1540 [NOIP2010 提高组] 机器翻译 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <bits/stdc++.h>

using namespace std;

bool v[1000];
int main() {

    int n,m;
    cin >> n >> m;
    queue<int> Q;
    int ans = 0;

    for (int i = 1; i <= m; i++) {
        int x;
        cin >> x;
        if (!v[x]) {
            v[x] = 1;
            if (Q.size() < n) {
                ans++;
                Q.push(x);
            } else {
                v[Q.front()] = 0;
                Q.pop();
                Q.push(x);
                ans++;
            }
        }
    }
    cout << ans << endl;

    return 0;
}

P3378 【模板】堆 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <bits/stdc++.h>

using namespace std;

int main() {

    int n,m;
    priority_queue <int,vector<int>,greater<int>> Q;
    cin >> n;
    while(n--){
        int op;
        cin >> op;
        if(op == 1){
            cin >> m;
            Q.push(m);
        }else if(op == 2){
            cout << Q.top() << endl;
        }else
            Q.pop();
    }

    return 0;
}

P1090 [NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

将数放入一个从小到大的优先队列中,优先队列里会自动排序,每次取最少的果子合并即可

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 10;

int main() {

    int n,m;
    priority_queue<int,vector<int>,greater<int>> Q;
    cin >> n;
    for(int i = 0;i < n;i ++){
        cin >> m;
        Q.push(m);
    }
    int ans = 0;
    while(Q.size() > 1){
        int u = Q.top();
        Q.pop();
        int v = Q.top();
        Q.pop();
        ans += u + v;
        Q.push(u + v);
    }
    cout << ans << endl;

    return 0;
}

B2071 余数相同问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这道题挺多方法能做的,不过由于单独用set的题较少,所以就用这道题简单的写一下set的用法,set会自动去重与排序,所以当存进去三个数之后set的长度还是等于1的话说明三个都是一样的.

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 10;

int main() {

    int n,m;
    int a,b,c;
    cin >> a >> b >> c;
    m = min({a,b,c});
    for(int i = 2;i <= m;i ++){
        set<int> s;
        s.insert(a % i),s.insert(b % i),s.insert(c % i);
        if(s.size() == 1){
            cout << i << endl;
            break;
        }
    }

    return 0;
}

P3613 【深基15.例2】寄包柜 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <bits/stdc++.h>

using namespace std;

int main() {

    int n,m;
    cin >> n >> m;
    map<pair<int,int>,int> mp;//map的key和value可以存很多种类型,但是double不太行,因为double的值是一个不精确的数
    while(m--){
        int op,i,j;
        cin >> op >> i >> j;
        if(op == 1){
            int x;
            cin >> x;
            mp[{i,j}] = x;
        }else
            cout << mp[{i,j}] << endl;
    }

    return 0;
}

P1097 [NOIP2007 提高组] 统计数字 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这道题你如果从1循环到1.5x\(10^9\)的话,无疑会超时,用for(auto [x,y] : mp)可以循环map里的值,x就代表了first,y代表second,如果你要for(auto i : mp)也是可以的,这时候i就是一个pair<int,int>类型的,你应当使用i.first和i.second

#include <bits/stdc++.h>

using namespace std;

int main() {

    int n,m;
    cin >> n;
    map<int,int> mp;
    for(int i = 0 ;i < n;i ++){
        cin >> m;
        mp[m]++;
    }
    for(auto [x,y] : mp)
        cout << x << ' ' << y << endl;

    return 0;
}

P1305 新二叉树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 10;

struct Node{
    char root;
    char left,right;
};
vector<Node> tree(128);
void traversal(char x){

    if(x == '*') return;
    cout << x;
    traversal(tree[x].left);
    traversal(tree[x].right);//这两个递归的执行顺序不同,最后输出的遍历结果也不同,这里是输出的前序遍历,想一想中序和后序遍历该怎样输出
};
int main() {

    int n,m;
    cin >> n;
    char root;

    for(int i = 1;i <= n;i ++){
        char a,b,c;
        cin >> a >> b >> c;
        if(i == 1) root = a;
        tree[a].left = b;
        tree[a].right = c;
        tree[b].root = tree[c].root = a;
    }

    traversal(root);

    return 0;
}

P1827 [USACO3.4] 美国血统 American Heritage - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

若觉得还是不太理解可以看看这两篇博客

已知先序中序序列求后序序列(详细解释)已知先序中序求后序题目Elephant_King的博客-CSDN博客

二叉树遍历:已知前、中求后序;已知后、中求前序。_zadarmo_的博客-CSDN博客

这题和下一题基本是已知先序和中序求后序, 已知后序和中序求先序的模版,理解之后也可以背下来,很多时候用到直接把板子写上去就行,或者写篇博客下什么的

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 10;

string s1,s2;

void traversal(int root,int start,int end){
/*
root  先序序列中当前递归层中根节点的下标
start 中序序列中子树的最左下标(子树开始的下标)
end   中序序列中子树的最右下标(子树结束的下标)
*/
    if(start>end)
        return ;
//递归结束的标志,因为子树的元素范围在下标[start,end]之内,当start>end的时候,说明以当前节点为空节点
    int i=start;
//这里的i相当于只在中序遍历中有效,这里的i对于查找根节点root的先序序列完全没有意义,仅代表root在中序序列中的下标位置    
    while(i<end && s1[i]!=s2[root]) //寻找root在中序序列中的位置	     
        i++;

    traversal(root + 1, start, i - 1);//递归左子树
    
    traversal(root + 1 - start + i, i + 1, end);//递归右子树

    cout << s1[i];
    
};
int main() {

    cin >> s1 >> s2;
    traversal(0,0,s2.size() - 1);

    return 0;
}

P1030 [NOIP2001 普及组] 求先序排列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 10;

string s1,s2;

void traversal(int root,int start,int end){

    if(start>end)
        return ;
    int i=start;
    while(i<end && s1[i]!=s2[root]) 	      
        i++;

    cout << s1[i];

    traversal(root - end + i - 1, start, i - 1);
    traversal(root - 1, i + 1, end);

};
int main() {

    cin >> s1 >> s2;
    traversal(s2.size() - 1,0,s2.size() - 1);

    return 0;
}
posted @ 2023-07-17 19:52  Ke_scholar  阅读(367)  评论(2编辑  收藏  举报