题目传送门
水题,疯狂打暴力就好了
C++ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 int n, a[N], res[] = {1 , 2 , 1 , 1 , 3 }, ans[] = {1 , 2 , 3 , 5 , 0 };void solve () { map<int , int > cnt; cin >> n; for (int i = 1 ; i <= n; i++) cin >> a[i]; for (int i = 1 , x; i <= n; i++) { x = a[i]; cnt[x]++; int check = 0 ; for (int j = 0 ; j < 5 ; j++) if (cnt[ans[j]] >= res[j]) check++; if (check == 5 ) { cout << i << endl; return ; } } cout << 0 << endl; }
# 题目大意给定 n n n 个数 ( a 1 , . . . , a n ) (a_1, ..., a_n) ( a 1 , . . . , a n ) ,再给一个教练需要的团队最小实力 x x x 一个团队的实力定义为: 团队人数 * 团队中的最小实力
,如果这个团队的实力 ≥ x \ge x ≥ x ,那么就可以组一只队伍 问:最多能组成多少队
# 题解排序之后,倒着找就好了
对于单人实力 ≥ x \ge x ≥ x 的,单人组队 反之,慢慢往前组队,直到实力 ≥ x \ge x ≥ x 位置C++ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 void solve () { int res = 0 ; cin >> n >> x; for (int i = 1 ; i <= n; i++) cin >> a[i]; sort (a + 1 , a + n + 1 ); int idx = n; while (idx >= 1 && a[idx] >= x) idx--, res++; for (int i = idx; i >= 1 ; i--) { if (a[i] * (idx - i + 1 ) >= x) res++, idx = i - 1 ; } cout << res << endl; }
# 题目大意给你一个 n n n ,问你能不能找到一个 1 1 1 到 n n n 的排列,满足循环移位 + 题目指定特性
什么是循环移位+题目指定特性? 一种 1 1 1 到 n n n 的排列组合,满足在每次循环移动中都有一个点,满足这个点的值和当前的位置相同
循环移位就是每次将尾部的数移到头部
# 题解是一道构造的水题
偶数个数不能组成题目要求的排列 奇数个数可以组成题目要求的排列 只需要奇数、偶数分开输出即可,此处选择先输出 2 2 2 到 n − 1 n-1 n − 1 的偶数,再输出 1 1 1 到 n n n 的奇数C++ 1 2 3 4 5 6 7 8 9 10 11 12 13 void solve () { cin >> n; if (!(n & 1 )) cout << -1 << endl; else { for (int i = 2 ; i <= n - 1 ; i += 2 ) cout << i << " " ; for (int i = 1 ; i <= n; i += 2 ) cout << i << " " ; cout << endl; } }
# 题目大意给定 n n n ,m m m ,k k k ,分别代表场馆长、宽和参赛人数,每个人要坐 ( i , j ) (i,j) ( i , j ) 的一个位置,如果一行中,有连起来的位置,就称为长凳 问,长凳的最小长度是?
# 题解尽可能分开排位置,一行最多有 p e o = ⌈ k / n ⌉ peo =\lceil{k / n}\rceil p e o = ⌈ k / n ⌉ 个人 对于该行,还剩下 m − p e o m - peo m − p e o 个空位,也就是将人分成 m − p e o + 1 m - peo + 1 m − p e o + 1 个部分,那么最多的人就是 ⌈ p e o m − p e o + 1 ⌉ \lceil{\frac{peo}{m - peo + 1}}\rceil ⌈ m − p e o + 1 p e o ⌉
C++ 1 2 3 4 5 6 7 8 void solve () { cin >> n >> m >> k; int peo = (k + n - 1 ) / n; int fm = m - peo + 1 ; cout << (peo + fm - 1 ) / fm << endl; }
# 题目大意对于 1 ≤ a , b ≤ n 1 \le a,b \le n 1 ≤ a , b ≤ n ,满足 l c m ( a , b ) g c d ( a , b ) \frac{lcm(a,b)}{gcd(a,b)} g c d ( a , b ) l c m ( a , b ) 是质数的个数。
# 题解做一点小变化:
g c d ( a , b ) l c m ( a , b ) = a g c d ( a , b ) ⋅ b g c d ( a , b ) {\frac{gcd(a,b)}{lcm(a,b)}}={\frac{a}{gcd(a,b)}·{\frac{b}{gcd(a,b)}}} l c m ( a , b ) g c d ( a , b ) = g c d ( a , b ) a ⋅ g c d ( a , b ) b
显然,如果它要是质数的话,a g c d ( a , b ) \frac{a}{gcd(a,b)} g c d ( a , b ) a 必须等于 1 1 1 ,也就是说,只需要满足 b a \frac{b}{a} a b 是质数即可
C++ 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 void init (int n) { notPrime[1 ] = 1 ; for (int i = 2 ; i <= n; i++) { if (!notPrime[i]) prime.push_back (i); for (auto p : prime) { if (p * i > n) break ; notPrime[p * i] = 1 ; if (i % p == 0 ) break ; } } } void solve () { int n; cin >> n; int ans = 0 ; for (auto t : prime) { if (t > n) break ; ans += n / t; } cout << ans << endl; }
拼劲全力还是无法战胜的 D P DP D P 题
# 题目大意给定一个 n × m n \times m n × m 的,由 X
和 #
组成的攀岩面
X
代表可以抓的,突出的岩石#
代表光滑的岩壁 现在一个人,已知他的手臂长度为 d d d 问这个人一共有多少条路径可以从第一行爬到最后一行?每层选择的点都不能低于 前一个点 每层最多选两个点 (只有两只手) (求出结果并用结果对 998244353998244353 998244353998244353 9 9 8 2 4 4 3 5 3 9 9 8 2 4 4 3 5 3 求模) # 数据范围2 ≤ n ≤ 2000 , 1 ≤ m , d ≤ 2000 2 \le n \le 2000,1 \le m,d \le 2000 2 ≤ n ≤ 2 0 0 0 , 1 ≤ m , d ≤ 2 0 0 0
# 题解对于本题,有两种攀爬方式:
向上爬 水平方向爬 对于有两种及以上移动方式的题目,不妨分开考虑,本题我们就可以考虑设置两个数组,一个代表从一层爬上新的一层的 u i , j u_{i,j} u i , j ,一个代表水平移动的 p_ u i , j u_{i,j} u i , j 为从上一层到这一层的能够到达终点的路径数p i , j p_{i,j} p i , j 为这一层上横向攀爬一次的能够到达终点的路径数 由题则可推出:u i , j = ∑ k = m a x ( j − d + 1 , 1 ) m i n ( j + d − 1 , m ) p i − 1 , k u_{i,j}=\sum\limits_{k=max(j-d+1,1)}^{min(j+d-1,m)} {p_{i-1,k}} u i , j = k = m a x ( j − d + 1 , 1 ) ∑ m i n ( j + d − 1 , m ) p i − 1 , k
p i , j = ∑ k = m a x ( j − 1 , 1 ) m i n ( j + d , m ) u i , k p_{i,j} = {\sum\limits_{k=max(j-1,1)}^{min(j+d,m)}{u_{i,k}}} p i , j = k = m a x ( j − 1 , 1 ) ∑ m i n ( j + d , m ) u i , k
C++ 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 const int N = 2e3 + 10 ;const int MOD = 998244353 ;int n, m, d;char s[N][N];int u[N][N], p[N][N], preU[N][N], preP[N][N];void init () { for (int i = 1 ; i <= n; i++) for (int j = 1 ; j <= m; j++) u[i][j] = p[i][j] = 0 ; } void solve () { cin >> n >> m >> d, init (); for (int i = 1 ; i <= n; i++) for (int j = 1 ; j <= m; j++) cin >> s[i][j]; for (int j = 1 ; j <= m; j++) { if (s[1 ][j] == 'X' ) u[1 ][j] = 1 ; preU[1 ][j] = (preU[1 ][j - 1 ] + u[1 ][j]) % MOD; } for (int j = 1 ; j <= m; j++) { if (s[1 ][j] == 'X' ) p[1 ][j] = (preU[1 ][min (j + d, m)] - preU[1 ][max (j - d - 1 , (int )0 )] + MOD) % MOD; preP[1 ][j] = (preP[1 ][j - 1 ] + p[1 ][j] + MOD) % MOD; } for (int i = 2 ; i <= n; i++) { for (int j = 1 ; j <= m; j++) { if (s[i][j] == 'X' ) u[i][j] = (preP[i - 1 ][min (j + d - 1 , m)] - preP[i - 1 ][max (j - d, (int )0 )] + MOD) % MOD; preU[i][j] = (preU[i][j - 1 ] + u[i][j]) % MOD; } for (int j = 1 ; j <= m; j++) { if (s[i][j] == 'X' ) p[i][j] = (preU[i][min (j + d, m)] - preU[i][max (j - d - 1 , (int )0 )] + MOD) % MOD; preP[i][j] = (preP[i][j - 1 ] + p[i][j]) % MOD; } } cout << preP[n][m] << endl; }