2022 杭电多校(2) 补题 2, 9, 12 , 8
2 C++ to Python 水题
签到,只要无视字母、下划线、冒号后输出即可
9 ShuanQ 逆元
题意:
已知
M是质数,。
加密公式:
解密公式:
给P和Q以及,求加密前的原始数据。
题解:
由
可得
证明
即:M是kM的一个比P,Q大的质因子。
而且显然最多只有一个质因子满足要求。
问题就变成了求解到的一个质因子M
求出m后,按照题目给的公式正常计算即可。
代码:
#include <iostream> #include <cstring> #include <vector> #include <bits/stdc++.h> #define endl '\n' //#pragma GCC optimize(3) #define int long long #define pii pair<int, int> using namespace std; const int N = 1e6 + 10; int getmaxprime(int n) { for (int i = 2; i <= sqrt(1.0 * n); i++) { while (n % i == 0) n = n / i; } return n; } int p, q, e; void solve() { cin >> p >> q >> e; int m = getmaxprime(p * q - 1); // cout<<k<<endl; if (m <= p || m <= q || m <= e) { cout << "shuanQ" << endl; } else { cout << ((e % m) * (q % m) + m) % m << endl; } } signed main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int t; cin >> t; while (t--) solve(); return 0; }
12 Luxury cruise ship 背包 数学
题意:
Kayzin 每天会将 7 或 31 或 365 个硬币放入他的存钱罐中。
现在 Kayzin 想知道他至少需要多少天才能“准确地”(不多也不少)凑齐购买豪华游轮的钱。
如果 Kayzin 不能“完全”凑齐购买豪华游轮的钱,打印 -1。
题解:
有一个定义:
两个质数x,y可以通过(a和b是任意整数)组成大于的任何一个整数。
通过这个定理可以发现:365可以由7和31这两个质数组成。
因此如果N较大,先用 365 将 N 减小到背包预处理的范围内,然后剩余的部分进行背包。
代码:
#include <iostream> #include <cstring> #include <vector> #include <bits/stdc++.h> #define endl '\n' #define int long long #define pii pair<int, int> using namespace std; int n, m, t; string st, ans; int x, y; int min(int a, int b) { if (a < b) return a; else return b; } int dp[600]; int a[3] = {7, 31, 365}; void solve() { cin >> t; while (t--) { x = 0, y = 0; cin >> n; for (int i = 1; i <= 600; i++) dp[i] = 0x3f3f3f3f3f; int cnt = 0; int tmp = (n - 180) / 365; int res = n; if (tmp > 0) { res -= tmp * 365; cnt += tmp; } for (int i = 0; i < 3; i++) { for (int j = a[i]; j <= res; j++) { dp[j] = min(dp[j - a[i]] + 1, dp[j]); } } if (dp[res] == 0x3f3f3f3f3f) cout << -1 << endl; else cout << dp[res] + cnt << endl; } } signed main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); solve(); return 0; }
8 Keyboard Warrior 哈希
题意:
给定一个操作序列 ( c , k ),若 c 为小写字符则往缓冲区添加 k 个 c c字符;若为 -则删除最后的 k 个字符。问是否存在一个时刻,给定的一个串 S 为缓冲区中字符串的一个连续子串。
思路:
使用哈希算法来比较两个字符串是否相同,然后模拟过程即可。
然后哈希算法如果按照正常的哈希算法,需要注意
一次性加入 k 个字符 ch 的哈希值,通过等比数列公式可以得到为,可以 的计算。
如果按照标程,就是没有这个问题。
标程的哈希公式:
#include <iostream> #include <cstring> #include <vector> #include <bits/stdc++.h> #define endl '\n' #define int long long #define pii pair<char, int> #define ull unsigned long long using namespace std; const int N = 1e6 + 10; const ull B = 131; string s; ull f[N]; pii stk[N]; void solve() { int n, m; cin >> n >> m; cin >> s; s = '1' + s; int dif = 1; for (int i = 2; i <= n; i++) if (s[i] != s[i - 1]) dif++; int be_len = 0, en_len = 0; for (int i = 1; i <= n && s[i] == s[1]; i++) be_len++; for (int i = n; i >= 1 && s[i] == s[n]; i--) en_len++; ull key = 0; for (int i = be_len + 1; i <= n - en_len;) { ull j = 1; while (s[i] == s[i + 1]) ++j, ++i; key += s[i] * B + j; ++i; } int p = 0; int flag = 0; char ju; int num; while (m--) { cin >> ju >> num; if (num == 0) continue; if (ju == '-') { while (num && p) { if (stk[p].second > num) stk[p].second -= num, num = 0; else num -= stk[p].second, p--; } } else { if (p && stk[p].first == ju) stk[p].second += num; else stk[++p] = {ju, num}; } if (p) f[p] = f[p - 1] + (stk[p].first * B + stk[p].second); if (dif == 1 && stk[p].second >= be_len) flag = 1; if (dif != 1 && p >= dif && stk[p - dif + 1].first == s[1] && stk[p - dif + 1].second >= be_len && stk[p].first == s[n] && stk[p].second >= en_len && f[p - 1] - f[p - dif + 1] == key) { flag = 1; } } if (flag) cout << "yes" << endl; else cout << "no" << endl; } signed main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int t = 1; // cout << "ss" << endl; cin >> t; while (t--) solve(); return 0; }
本文作者:kingwzun
本文链接:https://www.cnblogs.com/kingwz/p/16532977.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步