Educational Codeforces Round 17
传送门:http://codeforces.com/contest/762
A题:求出n的第k个因子,不存在则输出-1,直接sqrt暴力找一下就行了。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <string> #include <stack> #include <map> #include <set> #include <bitset> #define X first #define Y second #define clr(u,v); memset(u,v,sizeof(u)); #define in() freopen("data","r",stdin); #define out() freopen("ans","w",stdout); #define Clear(Q); while (!Q.empty()) Q.pop(); #define pb push_back using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 1e5 + 10; const int INF = 0x3f3f3f3f; vector <ll> V; int main() { V.pb(0); ll n, k; cin >> n >> k; ll m = sqrt((double)n); for (ll i = 1; i < m; i++) { if (n % i == 0) { V.pb(i); V.pb(n / i); } } if (n % m == 0) { if (m*m == n) V.pb(m); else V.pb(m), V.pb(n / m); } sort(V.begin(), V.end()); if (k >= V.size()) cout << -1 << endl; else cout << V[k] << endl; return 0; }
B题:有三种电脑,需要usb型的鼠标有a个,需要 PS/2型的鼠标有b个,两种鼠标都适配的电脑有c个,然后给你m种鼠标,每个鼠标价钱为vali,后面跟着型号,问适配所有电脑的最小花费。直接贪心就好了,先对价格进行排序,然后尽可能先把只能适配一种型号的匹配掉,再考虑两种通用的。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <string> #include <stack> #include <map> #include <set> #include <bitset> #define X first #define Y second #define clr(u,v); memset(u,v,sizeof(u)); #define in() freopen("data","r",stdin); #define out() freopen("ans","w",stdout); #define Clear(Q); while (!Q.empty()) Q.pop(); #define pb push_back using namespace std; typedef long long ll; typedef pair<int, string> pis; const int maxn = 1e5 + 10; const int INF = 0x3f3f3f3f; pis N[3*maxn]; int main() { int a, b, c, m; cin >> a >> b >> c; cin >> m; ll ans = 0; ll tol = a + b + c; for (int i = 0; i < m; i++) { cin >> N[i].X >> N[i].Y; } sort(N, N + m); for (int i = 0; i < m; i++) { if (N[i].Y == "USB") { if (a) { a--; ans += N[i].X; } else if (c) { c--; ans += N[i].X; } } else { if (b) { b--; ans += N[i].X; } else if (c) { c--; ans += N[i].X; } } } tol -= a + b + c; cout << tol << " " << ans << endl; return 0; }
C题:给你两个字符串str1和str2,问在str2中删除一段的字符串(连续的字符)后,str2能变成str1的子序列,求删除的这段字符串的长度最小时,str2的剩余字符串是什么。这题题解是哈希和尺取,不过我不知道怎么做,我的做法是直接处理出pre[]和suf[],pre[i]代表str2中前i个字符在str1中匹配的位置,比如pre[i]=k,那str2[1]到str2[i]这段字符串就是str1[1]到str1[k]这段字符串的子序列(字符串下标从1开始)。而suf数组和pre数组差不多,不过处理的是后缀。
举个例子,对于
abccba
ba
pre:2 6
suf:5 6
这样处理出来后,我们只要找到pre和suf的两个数pre[i]和suf[j],如果pre[i]<suf[j],那么我们取str2[1]到str2[pre[i]]加上str2[suf[j]]到str2字符串结尾这段字符串一定是str1的子序列,且这字符串也是str2删掉一段字符串后得来的。那么我们只需要枚举pre[i],然后二分找出suf[j]>pre[i]的数字,然后更新一下最值就行了。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <string> #include <stack> #include <map> #include <set> #include <bitset> #define X first #define Y second #define clr(u,v); memset(u,v,sizeof(u)); #define in() freopen("data","r",stdin); #define out() freopen("ans","w",stdout); #define Clear(Q); while (!Q.empty()) Q.pop(); #define pb push_back using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 1e5 + 10; const int INF = 0x3f3f3f3f; int pre[maxn], suf[maxn], lens1, lens2; char s1[maxn], s2[maxn]; void debug() { for (int i = 0; i <= lens2; i++) printf("%d ", pre[i]); puts(""); for (int i = 0; i <= lens2; i++) printf("%d ", suf[i]); puts(""); } void init() { lens1 = strlen(s1 + 1), lens2 = strlen(s2 + 1); int pos = 1; for (int i = 1; i <= lens2; i++) { pre[i] = INF; for (; pos <= lens1; pos++) { if (s2[i] == s1[pos]) { pre[i] = pos; pos++; break; } } } pos = lens1; for (int i = lens2; i > 0; i--) { suf[i] = -1; for (; pos > 0; pos--) { if (s2[i] == s1[pos]) { suf[i] = pos; pos--; break; } } } debug(); } void solve() { int ans = INF, l = 1, r = lens2; for (int i = 0; i <= lens2; i++) { int pos = upper_bound(suf + 1, suf + lens2 + 1, pre[i]) - suf; if (pre[i] == INF || suf[pos] == -1) continue; if (i >= pos) pos = i + 1; int Len = pos - i + 1; if (Len < ans) { ans = Len; l = i; r = pos; } } for (int i = 1; i <= l; i++) putchar(s2[i]); for (int i = r; i <= lens2; i++) putchar(s2[i]); puts(r - l <= lens2 ? "" : "-"); } int main() { scanf("%s%s", s1 + 1, s2 + 1); init(); solve(); return 0; }
2017-01-30 17:33:41
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~