牛客小白月赛73

1|0A 最小的数字


#include <bits/stdc++.h> using namespace std; #define int long long int32_t main() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); int n; cin >> n; cout << ((n+2ll)/3ll)*3ll << "\n"; return 0; }

2|0B 优美的GCD


#include <bits/stdc++.h> using namespace std; #define int long long int32_t main() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); int t; cin >> t; while( t -- ){ int n ; cin >> n; cout << n << " " << n*2 << "\n"; } return 0; }

3|0C 优美的序列


#include <bits/stdc++.h> using namespace std; #define int long long void solve(){ int n; cin >> n; vector<int> a(n); for( auto &i : a ) cin >> i; sort( a.begin(), a.end() ); for( int i = 1 ; i < n ; i ++ ){ if( a[i] == a[i-1] ){ cout << "-1\n"; return ; } } for( auto i : a ) cout << i << " "; cout << "\n"; } int32_t main() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); int t; cin >> t; while( t -- ) solve(); return 0; }

4|0DE Kevin喜欢零


没有写简单版本。

首先知道的是,末尾的0,一定是区间内2,5的数量决定的,如果可以计算出2,5的数量的最小值,就可以知道答案。

我们可以用前缀和维护2,5的数量,因为前缀和的单调性,所以可以枚举左端点并二分出右端点的取值范围。

#include <bits/stdc++.h> using namespace std; #define int long long void solve(){ int n , k; cin >> n >> k; vector<int> a(n+1) , b(n+1); for( int i = 1 , x ; i <= n ; i ++ ){ cin >> x; while( x % 2 == 0 ) x /= 2 , a[i] ++; while( x % 5 == 0 ) x /= 5 , b[i] ++; } for( int i = 1 ; i <= n ; i ++ ) a[i] += a[i-1] , b[i] += b[i-1]; auto f = [a,b]( int l , int r ){ return min( a[r] - a[l-1] , b[r] - b[l-1] ); }; int res = 0; for( int i = 1 , x , y , l , r , mid ; i <= n ; i ++ ) { l = i, r = n, x = -1; while (l <= r) { mid = (l + r) >> 1; if (f(i, mid) >= k) x = mid, r = mid - 1; else l = mid + 1; } l = i, r = n, y = -1; while (l <= r) { mid = (l + r) >> 1; if (f(i, mid) <= k) y = mid, l = mid + 1; else r = mid - 1; } if (x == -1 || y == -1) continue; if (f(i, x) != k || f(i, y) != k ) continue; res += max( 0ll, y - x + 1); } cout << res << "\n"; } int32_t main() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); int t; cin >> t; while( t -- ) solve(); return 0; }

5|0F Kevin的哈希构造


比较经典的 dp 思路吧。

f[i][j][x]表示前i位恰好j位相同且哈希值为x的方案是否存在。我们枚举状态后,在枚举出当前位选的字母c,则状态转移方程为f[i+1][j+(c=si)][(x×b+c)modp]|=f[i][j][x]

我们再维护前缀状态就可以还原出一个合法的串。

#include<bits/stdc++.h> using namespace std; #define int long long #define V vector #define ll long long #define mp make_pair int hashMod(string s, int b, int p) { int ans = 0; for (auto c: s) ans = (ans * b + c - 'a' + 1) % p; return ans; } int power(int x, int y, int p) { int ans = 1; while (y) { if (y & 1) ans = ans * x % p; x = x * x % p, y >>= 1; } return ans; } void solve() { int n, base, mod, k; string s; cin >> n >> base >> mod >> k >> s; V<V<V<bool>>> f(n + 1, V<V<bool>>(k + 2, V<bool>(mod + 1, 0))); V<V<V<int>>> preC(n + 1, V<V<int>>(k + 2, V<int>(mod + 1))); V<V<V<int>>> preH(n + 1, V<V<int>>(k + 2, V<int>(mod + 1))); int H = 0; // 计算原串 Hash 值 for (auto c: s) H = (H * base + c - 'a' + 1) % mod; f[0][0][0] = 1; for (int i = 0; i < n; i++) for (int j = 0; j <= k; j++) for (int x = 0; x < mod; x++) if (f[i][j][x]){ for (int c = 'a', nxt; c <= 'z'; c++) { nxt = (x * base + c - 'a' + 1 + mod) % mod; if (c == s[i]) { f[i + 1][j + 1][nxt] = 1; preC[i + 1][j + 1][nxt] = c; preH[i + 1][j + 1][nxt] = x; } else { f[i + 1][j][nxt] = 1; preC[i + 1][j][nxt] = c; preH[i + 1][j][nxt] = x; } } } if (!f[n][k][H]) { cout << "-1\n"; return; } string res = ""; for (int i = n, j = k, x = H; i >= 1; i--) { res += (char) preC[i][j][x]; if (preC[i][j][x] == s[i - 1]) x = preH[i][j][x], j--; else x = preH[i][j][x]; } reverse(res.begin(), res.end()); cout << res << "\n"; } int32_t main() { int t; cin >> t; for (; t; t--) solve(); }

6|0G MoonLight的冒泡排序难题


打表找规律,发现分子的数列是0,1,7,46,326,2556,,然后查到分子的值的递推式是ai=ai1×i+(i1)(i1)!

分子其实就是全排列

#include <bits/stdc++.h> using namespace std; #define int long long const int mod = 998244353; int power( int x , int y ){ int ans = 1; while( y ){ if( y & 1 ) ans = ans * x % mod; x = x * x % mod , y >>= 1; } return ans; } int inv( int x ){ return power( x , mod - 2 ); } const int N = 2e5+5; int32_t main() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); vector<int> fact(N+1) , invFact(N+1) , f(N+1); fact[0] = 1 , invFact[0] = inv( fact[0] ); for( int i = 1; i <= N ; i ++ ) fact[i] = fact[i-1] * i % mod , invFact[i] = inv(fact[i]); f[1] = 0; for( int i = 2 ; i <= N ; i ++ ) f[i] = ( f[i-1]*i % mod + (i-1)*fact[i-1] % mod ) % mod; int t ; cin >> t; while( t -- ){ int x; cin >> x; cout << f[x] * invFact[x] % mod << "\n"; } return 0; } /* * 0 1 7 46 326 2556 22212 212976 */

__EOF__

本文作者PHarr
本文链接https://www.cnblogs.com/PHarr/p/17450416.html
关于博主:前OIer,SMUer
版权声明CC BY-NC 4.0
声援博主:如果这篇文章对您有帮助,不妨给我点个赞
posted @   PHarr  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示