2024年3月ZZUACM 招新赛题解

2024年3月ZZUACM 招新赛

题号 题目
A 区间次大值
B 上课签到
C 魔法森林(一)
D 魔法森林(二)
E LOP
F 跳格子
G 猜数字
H 抽卡记录
I 安达的二维矩阵
J 安达的数字手术
K 跳楼梯
L 前缀和

A 区间次大值—循环/签到题

题目描述

给定一个 n n n的全排列 a i a_i ai,下标为 1 − n 1-n 1n,请你输出所有 l < r l<r l<r的区间 [ l , r ] [l,r] [l,r]中次大数之和。

n n n的全排列指一个长为 n n n的数组, 1 , 2... N 1,2...N 1,2...N每个数字出现且只出现一次。

输入格式

第一行一个整数表示 n n n

第二行 n n n个整数表示 n n n的全排列

输出格式

输出一行一个正整数表示答案

输入输出样例

样例输入 #1
4
4 1 3 2
样例输出 #1
12
样例解释 #1

区间 [ 1 , 2 ] [1,2] [1,2]的次大值为 1 1 1,区间 [ 1 , 3 ] [1,3] [1,3]的次大值为 3 3 3,区间 [ 1 , 4 ] [1,4] [1,4]的次大值为 3 3 3,区间 [ 2 , 3 ] [2,3] [2,3]的次大值为 1 1 1,区间 [ 2 , 4 ] [2,4] [2,4]的次大值为 2 2 2,区间 [ 3 , 4 ] [3,4] [3,4]的次大值为 2 2 2。因此答案为 1 + 3 + 3 + 1 + 2 + 2 = 12 1+3+3+1+2+2=12 1+3+3+1+2+2=12

数据范围与约定

数据保证 n ≤ 1 0 3 n\leq 10^3 n103 1 ≤ a i ≤ n 1\leq a_i \leq n 1ain。如果 i ≠ j i\neq j i=j,则 a i ≠ a j a_i \neq a_j ai=aj

题解

先看数据范围可二层循环,可直接暴力,第一层循环代表左端点,第二层右端点,维护一个最大值和次大值即可

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

using namespace std;

int main() {
   
   
    int n; cin >> n;
    vector<int> a(n + 1, 0);
    for(int i = 0; i < n; i ++) cin >> a[i];
    
    int res = 0;
    for(int i = 0; i < n - 1; i ++) {
   
   
        int max1 = max(a[i], a[i + 1]);
        int max2 = min(a[i], a[i + 1]);
        res += max2;
        for(int j = i + 2; j < n; j ++) {
   
               
            if(a[j] > max1) {
   
   
                max2 = max1;
                max1 = a[j];
            } else if(a[j] > max2) {
   
   
                max2 = a[j];
            }
            res += max2;
        }
    }
     
    cout << res << endl;
}

B 上课签到—二分+最短路

题目描述

某一天飞云从宿舍起床,但他上课快迟到了,他想要尽可能快的到达教室。他要在上课之前到达教室签到,换句话说,如果还有 h h h分钟上课,他必须要在小于等于 h h h分钟内到达教室。现在将宿舍,十字路口,教室抽象成一张无向图,含有 n n n个点和 m m m条边。由于路况的不同,每到达一个点都要消耗 a i a_i ai体力值(起始位置和终止位置也算),每经过一条边需要 w w w分钟。而对于飞云来说,由于体力可以恢复,所以他只需要知道路径上的最大体力消耗。现在飞云向聪明的你求助,在不迟到的情况下,所选路径中最大体力消耗的最小值是多少。

输入格式

第一行读入五个数 n , m , s t , e d , h n,m,st,ed, h n,m,st,ed,h(分别无向图的点数,边数,起始位置,终止位置,距离上课所剩的时间(单位:分钟))

接下来n行分别读入 n n n个数 a i a_i ai(每个点消耗的体力值)

接下来m行读入 x , y , w x,y,w x,y,w(分别代表无向边的两点和路上所花费的时间)

输出格式

输出一行代表最大消耗体力的最小值,若会迟到,则输出 − 1 -1 1

输入输出样例

样例输入 #1
4 4 1 4 8
8
5
6
10
1 3 4
2 4 1
2 1 2
3 4 9
样例输出 #1
10

样例解释

只能选择路径1->2->4,花费 3 3 3分钟,路径上最大体力消耗是到达 4 4 4的时候,花费 10 10 10.

数据范围与约定

$1 \le n \le 10^4 $, 1 ≤ m ≤ 2 ∗ 1 0 4 1 \le m\le 2*10^4 1m2104 1 ≤ a i , z , h ≤ 1 0 7 1 \le a_i,z, h \le 10^7 1ai,z,h107 1 ≤ x , y ≤ n 1 \le x,y \le n 1x,yn

题解

首先,对于最大…的最小,都可以考虑二分思路。其次,对于双权值问题,如果可以开二维,是可以跑二维的,但是明显这题开不了二维(会爆栈和TLE),并且有单调性质,所以考虑二分。

单调性质:设最大体力消耗是x,如果x满足条件(即可以找到一条路径,路径的权值和小于等于h并且点权值都小于等于x),那么大于x的也满足条件。所以考虑二分。

然后判断是不是满足跑一下dijkstra最短路即可。

#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
#define PII pair<int, int>
#define int long long
 
const int N = 1e4 + 10;
int a[N];
 
struct edge {
   
   
    int v, w;
};
vector<edge> e[N];
int n, m, st, ed, h;
int dist[N];
int vis[N];

bool check(int x) {
   
    // Dijkstra最短路
    for (int i = 1; i <= n; i++) {
   
   
        dist[i] = 1e18;
        vis[i] = 0;
    }
    priority_queue<PII, vector<PII>, greater<PII>> q;
    q.push({
   
   0, st});
    dist[st] = 0;
 
    if (a[st] > x) return false;
 
    while (q.size()) {
   
   
        auto now = q.top();
        q.pop();
        int u = now.second;
        if (vis[u]) continue;
        vis[u] = 1;
        for (auto t: e[u]) {
   
   
            int v = t.v, w = t.w;
            if (dist[v] > dist[u] + w && a[v] <= x) {
   
   
                dist[v] = dist[u] + w;
                q.push({
   
   dist[v], v});
            }
        }
    }
 
    return dist[ed] <= h;
}
 
signed main() {
   
   
    cin >> n >> m >> st >> ed >> h;
    for (int i = 1; i <= n; i++) {
   
   
        cin >> a[i];
    }
    
    for (int i = 1; i <= m; i++) {
   
   
        int u, v, w; cin >> u >> v >> w;
        e[u].push_back({
   
   v, w});
        e[v].push_back({
   
   u, w});
    }
 
    int l = 1, r = 1e7 + 10;
    while (l < r) {
   
   
        int mid = l + r >> 1;
        if (check(mid)) r = mid;
        else l = mid + 1;
    }
 
    if (l == 1e7 + 10) cout << -1 << '\n';
    else cout << l << '\n';
}

C 魔法森林(一)—模拟

题目描述

小G来到了向往已久的魔法森林,并且想要探索其中的宝藏。

具体的,魔法森林可以看作是一个 n × m n\times m n×m的矩阵,其中矩阵的每个位置都可以用一对坐标表示,例如 ( i , j ) (i,j) (i,j) i i i行第 j j j列的位置。魔法森林中每个位置的具体信息可以用一个字符来表示:

若当前位置字符是’.',则表示当前位置为空地,小G可以自由行走。

若当前位置字符是’#',则表示当前位置为障碍,小G不可以通过。

另外作为魔法森林,魔法传送阵是其特色,具体的来说若字符是大写的英文字母,则

### 关于202412月USACO铜组比赛题目解答 #### 问题背景与概述 针对202412月USACO铜组的比赛,具体题目细节尚未公布。然而,基于以往的经验和模式,可以推测该次竞可能涉及的基础算法概念以及解决问题的方法。 #### 使用双数组存储信息 当遇到需要多次访问同一元素的情况时,采用两个独立的数组别记录这些元素的信息是一种有效策略[^1]。这种方法特别适用于那些具有重复操作特性的场景,能够简化逻辑并提高效率。 #### 清零机制的应用 对于某些特定条件下使用的临时变量或辅助结构(比如计数器`num`),适时地将其重置为初始状态是非常重要的。这有助于防止前一次计算残留影响后续的结果准确性。 #### 时间复杂度考量 考虑到实际应用场景中的数据规模较小,即使实现较为复杂的$O(n^2)$甚至更高阶的时间复杂度算法也是可行的选择。这是因为小量级的数据集使得高时间复杂度带来的性能损耗变得微不足道。 #### 枚举法解决交互型游戏类问题 面对像“Why Did the Cow Cross the Road II”这样的互动式博弈论问题,可以通过枚举所有可能性来进行模拟推演。例如,在两轮游戏中根据不同角色的行为组合来预测最终得情况,并据此得出最优解路径[^2]。 #### 动态规划求解资源配优化模型 以“最小化草地数量”的挑战为例,通过设定动态转移方程,逐步构建起从局部到全局的最佳解决方案框架。这里的关键在于合理定义状态表示方法及其之间的转换关系,从而确保找到满足约束条件下的最优点[^3]。 #### 特殊规则下胜负判定逻辑设计 在类似于“贝茜和朋友玩的游戏”这类含有特殊胜利条件的任务里,重点是要理解规则背后的数学原理。利用回文特性作为判断依据之一,配合其他因素综合考虑,进而形成一套完整的决策流程用于确定胜者身份[^4]。 #### 处理大规模输入输出技巧 针对较大规模的数据处理需求,如岛屿面积统计等问题,则需引入诸如离散化技术等高级手段加以应对。通过对原始坐标系内的点位进行适当变换映射成的有序序列,既减少了内存占用又加快了运算速度[^5]。 ```python def solve_palindrome_game(T, samples): results = [] for sample in samples: stones = list(map(int, str(sample))) while sum(stones) > 0 and is_palindromic(sum(stones)): # Bessie takes palindromic number of stones first taken_by_bessie = find_largest_palindrome_less_than_or_equal_to(sum(stones)) stones -= [taken_by_bessie] if sum(stones) == 0: break # Friend then takes remaining stones which must be non-palindromic now friend_takes_rest() winner = 'B' if sum(stones)==0 else 'E' results.append(winner) return ''.join(results) def is_palindromic(num): num_str = str(abs(num)) reversed_num_str = num_str[::-1] return num_str == reversed_num_str def find_largest_palindrome_less_than_or_equal_to(max_value): for i in range(max_value, 0, -1): if is_palindromic(i): return i def friend_takes_rest(): pass # Example usage with multiple test cases represented by T=3 here. print(solve_palindrome_game(3,[7, 9, 1])) ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_WAWA鱼_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值