写在前面
由于是弱校,只有个铜牌,当做经验吧。
比赛过程
本人因经验较少,充当读题的角色(也算躺了),提供几个题目的思路。
L题 Loong 一开始因为没有读题完整,导致L题 WA一次 ,给队友增加罚时 , 原因是要查找 输入$N$年之后的龙年,读成$N$年最近的龙年(包括前后的最近)
接下来做的是 B 题 Black Friday,相较于 L题 较为简单,一样是签到题,所以是一次过了。这里就不多说了。
再下来是E题Epsilon Estuary,我和另外一个队友读题,发现一样是模拟+贪心,只需要逮着 血量最大的史莱姆 模拟操作即可,但是在编写代码中,while的判断条件写成了 while(health) ,这样会导致 health < 0 导致无限循环,然后不出意外的 TLE 了,为下图中的 while(big) 处
接下来做F题 Farewell GXCPC 时,我和队友读题发现有点类似背包问题,可能是没有注意到 数据量,在每次处理数据的时候,都进行一次dp操作,导致了TLE,后来提出在操作用例前进行dp操作,读取区间即可。但是还是 WA了5次
J 题Judge System with Random 可能是本场比赛的转折点了,到这就断层了(),罚时如果少,且A了这一题,可以拿到银牌了(),也许是我第一次参加这个比赛,不知道这个罚时的规则,看了多次的题目都没有看懂这个题。但是只有队长看懂了。他是选择了二分,当时我没有反应过来(哭了)。用二分查找那个边界,拿到二分的有边界 $r$ ,则可以得到答案,但是因为卡了一小时也没再看题目,也许是少了 $pow(2,n+m) % mod$,导致一直WA,这就是队长当时了思路(估计)。下次还是得多看题目,不能因为搞懂大概题意就一直做题,要适当的回归题目本身。
然后就一直在试J题,直到比赛结束(),然后大败而归
结果
补题时间
L Loong
大概思路就是,先打表通过 2024 年 $-12$ or $+12$标记龙年,在用循环访问数组直到数组数值为龙年,输出$i$的位置即可,代码就直接用java写吧,后面基本都是用cpp写的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import java.util.Scanner;public class Main { public static void main (String[] args) { int [] arr = new int [10006 ]; int y = 2024 ; while (y <= 10004 ) { arr[y] = 1 ; y += 12 ; } y = 2024 ; while (y > 0 ) { arr[y] = 1 ; y -= 12 ; } Scanner sr = new Scanner (System.in); int idx = sr.nextInt() + 1 ; while (arr[idx] != 1 ) idx++; System.out.println(idx); } }
B Black Friday
大概题意就是,输入 a b两个数值 计算,Eva所能接受的打折的游戏,直接循环
计算每个游戏的 $rate=\frac{p_i-q_i}{p_i}$ 。
如果 $rate \ge \frac{a}{b}$ 累加结果并输出即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 import java.io.IOException;import java.io.StreamTokenizer;public class Main { static StreamTokenizer st = new StreamTokenizer (System.in); static int nextInt () throws IOException{ st.nextToken(); return (int )st.nval; } public static void main (String[] args) throws IOException{ int n = nextInt(); int a = nextInt(); int b = nextInt(); double accept = (double )a / b; long sum = 0 ; for (int i = 0 ; i < n; i++){ int p = nextInt(); int q = nextInt(); double rate = (double )(p - q) / p; if (rate >= accept) { sum += q; } } System.out.println(sum); } }
E Epsilon Estuary
每次攻击 $n$个史莱姆,每个史莱姆会分裂出 $\left \lfloor \frac{x}{2} \right \rfloor$和 $\left \lceil \frac{x}{2} \right \rceil$,我们每次选择最大血量的史莱姆攻击即可,累加攻击次数,即可得到结果,时间复杂度为 $O(n logn)$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include <bits/stdc++.h> using namespace std;#define ll long long void solve () { int n; ll y; cin >> n >> y; ll big = 0 ; for (int i =0 ;i<n;i++){ ll v; cin >> v; if (v > big) big = v; } ll cnt = 0 ; while (big > 0 ){ big = big - y; big = ceil (big / 2.0 ); cnt++; } cout << cnt << "\n" ; } int main () { ios::sync_with_stdio (false ); cin.tie (0 ),cout.tie (0 ); int t; cin >> t; while (t--) solve (); return 0 ; }
F FareWell GXCPC
很明显是一个背包的问题,建立dp表,把5000内的情况全部考虑,再预处理区间的最大值,最后输出结果就可以了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include <bits/stdc++.h> using namespace std;const int MAXN = 5e3 ;int n,q;int main () { cin >> n >> q; vector<int > dp (MAXN+1 ,-0x3f3f3f ) ; dp[0 ] = 0 ; for (int i = 0 ;i<n;i++){ int d,f; cin >> d >> f; for (int j = MAXN;j>=d;j--) dp[j] = max (dp[j],dp[j-d]+f); } vector<vector<int >> res (MAXN+1 ,vector <int >(MAXN+1 ,-1 )); for (int i = 1 ;i<=MAXN;i++) for (int j = i ;j<=MAXN;j++) res[i][j] = max (res[i][j-1 ],dp[j]); while (q--) { int l ,r; cin >> l >> r; cout << res[l][r] << endl; } return 0 ; }
J Judge System with Random
大概题意是: Colin 和 Eva 对比罚时,谁小谁赢,输入的时候对数据进行处理
for(int i =0;i<n;i++) cin >> x[i]; x[i] += 20 * i;
i为0的时候就是第一次提交成功,往下就是提交失败的,加上罚时,不难发现 提交的时间是 单调上升的,那么说明结果也是同样的,会存在一个边界,找到那个边界的 右 r ,带入 pow(2, r),使用快速幂即可计算得到结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 #include <bits/stdc++.h> using namespace std;#define ll long long const int N = 1e5 + 1 ;vector<int > x (N,0 ) ;vector<int > y (N+1 ,0 ) ;int n,m;ll qpow (ll a, ll b, ll m) { a %= m; ll res = 1 ; while (b > 0 ) { if (b & 1 ) res = res * a % m; a = a * a % m; b >>= 1 ; } return res; } bool cmp (const int & x, const int & y) { return x <= y; } const int mod= 998244353 ;int main () { cin >> n >> m; for (int i =0 ;i<n;i++){ cin >> x[i]; x[i] += 20 * i; } for (int i = 0 ; i < m; i++){ cin >> y[i]; y[i] += 20 * i; } y[m] = 1e9 ; ll ans = 0 ; for (int i = n-1 ;i>=0 ;i--) { auto it = upper_bound (y.begin (),y.begin () + m,x[i],cmp); int j = distance (y.begin (),it); ans += qpow (2 ,(n - i) + (m - j - 1 ) ,mod); ans %= mod; } cout << ans; return 0 ; }
D Dune