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;
    }
    
  • 相关阅读:
    C#反射概念以及实例详解【转】
    .NET(C#):使用反射来获取枚举的名称、值和特性【转】
    探求C#.Net中ArrayList与Array的区别 【转】
    C#中IList<T>与List<T>的区别感想【转】
    C# System.Guid.NewGuid() 【转】
    回车键触发按钮事件
    MVC中Json的使用:Controller中Json的处理【转】
    关于优化性能<主要是速度方面>的个人心得 【转】
    ca72a_c++_标准IO库:面向对象的标准库
    ca71a_c++_指向函数的指针_通过指针调用函数txwtech
  • 原文地址:https://www.cnblogs.com/IzumiSagiri/p/14998254.html
Copyright © 2011-2022 走看看