• 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;
    }
    
  • 相关阅读:
    20080619 SQL SERVER 输入 NULL 的快捷键
    20090406 Adobe的“此产品的许可已停止工作”错误的解决办法
    20080908 Office Powerpoint 2007 不能输入中文的解决办法
    20080831 ClearGertrude Blog Skin 's cnblogs_code class
    20080603 Facebook 平台正式开放
    20080519 安装 Microsoft SQL Server 2000 时提示 创建挂起的文件操作
    test
    Linux—fork函数学习笔记
    SOA的设计理念
    Why BCP connects to SQL Server instance which start with account of Network Service fail?
  • 原文地址:https://www.cnblogs.com/IzumiSagiri/p/14998254.html
Copyright © 2020-2023  润新知