zoukankan      html  css  js  c++  java
  • 2021NUAA暑期模拟赛部分题解

    比赛链接:2021 nuaa 暑期模拟赛
    比赛码:1234554321



    D - 然叔的玩具熊

    答案是单调的,考虑每个数能成为答案的最大区间长度,即这个数是区间最小值,所以找每个数前后第一个小于它的即可得到最长长度,短的长度可以通过后缀最大传递下来。
    单调栈可以(O(n))

    #include <cstdio>
    #include <iostream>
    #include <stack>
    using namespace std;
    
    int n, h[200010];
    int len[200010];  // len[i]表示大小为i的分组中力量的最大值
    struct node {  // num:数值  loc:能被作为答案的最大区间的最左端位置
        int num, loc;
    };
    stack<node> st;
    
    int main() {
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &h[i]);
        }
        h[++n] = 0;  // 在序列末尾加上0使其他数都出栈
        for (int i = 1; i <= n; ++i) {
            if (st.empty()) {
                st.push(node{h[i], i});
            } else if (!st.empty() && h[i] >= st.top().num) {
                st.push(node{h[i], i});
            } else {
                int nowloc = i;
                while (!st.empty() && st.top().num > h[i]) {
                    int loc = st.top().loc, x = st.top().num;
                    st.pop();
                    nowloc = loc;            // 区间变大,最左端更新
                    if (len[i - loc] < x) {  // 更新答案
                        len[i - loc] = x;
                    }
                }
                st.push(node{h[i], nowloc});
            }
        }
        for (int i = n - 1; i >= 1; --i) {  // 从后往前更改答案使其单调递减
            if (len[i] < len[i + 1]) {
                len[i] = len[i + 1];
            }
        }
        for (int i = 1; i <= n - 1; ++i) {
            printf("%d ", len[i]);
        }
        return 0;
    }
    

    H - Good Array

    签到题,分两种情况直接输出即可。

    #include <iostream>
    using namespace std;
    int t, n, s;
    int main() {
    	s = 0;
    	cin >> t;
    	while (t--) {
    		s = 0;
    		int x;
    		cin >> n;
    		for (int i = 1; i <= n; ++i) {
    			cin >> x;
    			s += x;
    		}
    		if (s >= n) {
    			cout << s - n << endl;
    		} else {
    			cout << 1 << endl;
    		}
    	}
    	return 0;
    }
    

    I - 恶灵传说

    首先通过广度优先搜索找出所有存在危险的城市,通过堆优化时间。
    再通过最短路找到最小花费,安全城市花费为P,危险城市花费为Q,被占领城市花费为无穷大即不可走。

    #include <iostream>
    #include <queue>
    using namespace std;
    
    int n, m, k, s, p, q, x;
    int vis[100010];  // 0 安全 1 危险 2 被占领 3 被占领
    int cnt, head[100010];
    long long dis[100010];
    struct Edge {
        int len, v, next;
    } edge[400010];
    struct dj_node {
        int id;
        long long dis;
        bool operator<(const dj_node &obj) const { return dis > obj.dis; }
    };
    struct bfs_node {
        int id, dis;
        bool operator<(const bfs_node &obj) const { return dis < obj.dis; }
    };
    priority_queue<bfs_node> bfs_pq;
    
    void addEdge(int u, int v, int w) {
        edge[++cnt].v = v;
        edge[cnt].len = w;
        edge[cnt].next = head[u];
        head[u] = cnt;
        // 无向图
        edge[++cnt].v = u;
        edge[cnt].len = w;
        edge[cnt].next = head[v];
        head[v] = cnt;
    }
    
    void find_danger() {  // 堆优化广搜
        while (!bfs_pq.empty()) {
            int id = bfs_pq.top().id, dis = bfs_pq.top().dis;
            bfs_pq.pop();
            if (vis[id] != 1 && vis[id] != 3) {
                for (int i = head[id]; i; i = edge[i].next) {
                    if (edge[i].len <= dis) {
                        bfs_pq.push(bfs_node{edge[i].v, dis - edge[i].len});
                    }
                }
                if (vis[id] == 0) {
                    vis[id] = 1;
                } else if (vis[id] == 2) {
                    vis[id] = 3;
                }
            }
        }
    }
    
    void dijkstra() {  // 最短路
        priority_queue<dj_node> dj_pq;
        for (int i = 1; i <= n; ++i) {
            dis[i] = 0x3f3f3f3f;
        }
        dis[1] = 0;
        dj_pq.push(dj_node{1, 0});
        while (!dj_pq.empty()) {
            int id = dj_pq.top().id;
            long long Dis = dj_pq.top().dis;
            dj_pq.pop();
            if (Dis > dis[id]) continue;
            for (int i = head[id]; i; i = edge[i].next) {
                if (vis[edge[i].v] == 3) {
                    continue;
                } else if (vis[edge[i].v] == 1) {
                    if (dis[edge[i].v] > Dis + q) {
                        dis[edge[i].v] = Dis + q;
                        dj_pq.push(dj_node{edge[i].v, dis[edge[i].v]});
                    }
                } else if (vis[edge[i].v] == 0) {
                    if (dis[edge[i].v] > Dis + p) {
                        dis[edge[i].v] = Dis + p;
                        dj_pq.push(dj_node{edge[i].v, dis[edge[i].v]});
                    }
                }
            }
        }
    }
    
    int main() {
        cin >> n >> m >> k >> s >> p >> q;
        for (int i = 1; i <= k; ++i) {
            cin >> x;
            vis[x] = 2;
            bfs_pq.push(bfs_node{x, s});
        }
        int u, v, w;
        for (int i = 1; i <= m; ++i) {
            cin >> u >> v >> w;
            addEdge(u, v, w);
        }
        find_danger();
        dijkstra();
        if (vis[n] == 3) {
            cout << -1 << endl;
        } else if (vis[n] == 1) {
            cout << dis[n] - q << endl;
        } else {
            cout << dis[n] - p << endl;
        }
        return 0;
    }
    

    K - 数字矩阵

    标记多少行多少列有(0)即可,如果(i)(j)列有(0),答案即为(i*m+j*n-i*j)

    #include <iostream>
    using namespace std;
    
    int x[2010], y[2010], ii, jj, n, m;
    
    int main() {
        cin >> n >> m;
        int num;
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= m; ++j) {
                cin >> num;
                if (!num) {
                    x[i] = 1;
                    y[j] = 1;
                }
            }
        }
        for (int i = 1; i <= n; ++i) {
            ii += x[i];
        }
        for (int j = 1; j <= m; ++j) {
            jj += y[j];
        }
        cout << ii * m + jj * n - ii * jj << endl;
        return 0;
    }
    
  • 相关阅读:
    Django(app的概念、ORM介绍及编码错误问题)
    Django(完整的登录示例、render字符串替换和redirect跳转)
    Construct Binary Tree from Preorder and Inorder Traversal
    Single Number II
    Single Number
    Binary Tree Level Order Traversal II
    Binary Tree Level Order Traversal
    Binary Tree Zigzag Level Order Traversal
    Recover Binary Search Tree
    Add Binary
  • 原文地址:https://www.cnblogs.com/IzumiSagiri/p/14998254.html
Copyright © 2011-2022 走看看