SMU Spring 2023 Trial Contest Round 9
A. Wrong Subtraction
#include <bits/stdc++.h>
using namespace std;
int32_t main() {
int n, k;
cin >> n >> k;
while (k--) {
if (n % 10 == 0) n /= 10;
else n--;
}
cout << n;
return 0;
}
B. Two-gram
#include <bits/stdc++.h>
using namespace std;
int32_t main() {
int n;
cin >> n;
string s;
cin >> s;
map<string, int> cnt;
for (int i = 0; i + 1 < n; i++)
cnt[s.substr(i, 2)]++;
int val = 0;
string res = "";
for (auto [k, v]: cnt) {
if (v > val) val = v, res = k;
}
cout << res << "\n";
return 0;
}
C. Less or Equal
排序,如果第\(k\) 大和第\(k+1\)大不同输出第\(k\)大,否则输出\(-1\)
特判\(k=0,k=n\)
#include <bits/stdc++.h>
using namespace std;
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int32_t main() {
int n = read(), k = read();
vector<int> a(n);
for (auto &i: a) i = read();
sort(a.begin(), a.end());
if (k == 0) {
if (a[0] == 1) cout << "-1";
else cout << "1";
} else if (k == n) cout << a.back();
else {
if (a[k] == a[k - 1]) cout << "-1";
else cout << a[k - 1] << "\n";
}
return 0;
}
D. Divide by three, multiply by two
建图跑搜索即可。复杂度\(O(\frac{n^2}{4})\)
#include <bits/stdc++.h>
using namespace std;
#define int long long
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int n;
vector<vector<int>> e;
vector<int> res, a;
vector<bool> vis;
void dfs(int x) {
if (res.size() == n) {
for (auto i: res) printf("%lld ", a[i]);
exit(0);
}
for (auto v: e[x]) {
if (vis[v]) continue;
vis[v] = true, res.push_back(v);
dfs(v);
vis[v] = false, res.pop_back();
}
return;
}
int32_t main() {
n = read();
a = vector<int>(n + 1);
e = vector<vector<int>>(n + 1);
vis = vector<bool>(n + 1, false);
for (int i = 1; i <= n; i++) a[i] = read(), e[0].push_back(i);
for (int i = 1; i <= n; i++)
for (int j = 1; j < i; j++) {
if (a[i] * 2 == a[j]) e[i].push_back(j);
if (a[i] * 3 == a[j]) e[j].push_back(i);
if (a[j] * 2 == a[i]) e[j].push_back(i);
if (a[j] * 3 == a[i]) e[i].push_back(j);
}
dfs(0);
return 0;
}
E. Cyclic Components
并查集判断连通性,联通块内每个点的度数都是 2 的即为题面要求的环
#include <bits/stdc++.h>
using namespace std;
#define int long long
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
struct dsu {
vector<int> fa;
dsu(int n = 0) {
fa = vector<int>(n + 1, -1);
}
int getfa(int x) {
if (fa[x] < 0) return x;
return fa[x] = getfa(fa[x]);
}
bool merage(int x, int y) {
x = getfa(x), y = getfa(y);
if (x == y) return false;
if (fa[x] > fa[y]) swap(x, y);
fa[x] += fa[y], fa[y] = x;
return true;
}
bool check(int x, int y) {
x = getfa(x), y = getfa(y);
return x == y;
}
};
int32_t main() {
int n = read();
vector<int> d(n + 1);
dsu D(n);
for (int x, y, m = read(); m; m--) {
x = read(), y = read(), d[x]++, d[y]++;
D.merage(x, y);
}
int res = 0;
map<int, vector<int>> t;
for (int i = 1; i <= n; i++) t[D.getfa(i)].push_back(i);
for (auto it: t) {
int f = 1;
for (auto i: it.second)
if (d[i] != 2) {
f = 0;
break;
}
res += f;
}
cout << res;
return 0;
}
F. Consecutive Subsequence
首先\(O(n)\)的 dp 求最长连续子序列的长度和最后一个数。然后就可以还原出子序列中每个数的值,贪心的从后先前选择可选的最大值即可。
#include <bits/stdc++.h>
using namespace std;
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int32_t main() {
int n = read();
map<int, int> f;
map<int,vector<int>> cnt;
for (int x , i = 1 ; i <= n; i ++ )
x = read(), f[x] = max(1, f[x - 1] + 1) , cnt[x].push_back(i);
int res = 0 , t ;
for( auto [ k , v ] : f ){
if( v > res ) res = v , t = k;
}
cout << res << "\n";
vector<int> ans;
for( int i = res , p = INT_MAX ; i ; i -- , t -- ){
while( cnt[t].back() >= p ) cnt[t].pop_back();
ans.push_back( cnt[t].back() ) , p = cnt[t].back();
}
reverse(ans.begin(), ans.end());
for( auto i : ans ) cout << i << " ";
return 0;
}