SMU Spring 2023 Trial Contest Round 9
A. Wrong Subtraction
在k次操作里, 将n的最后一位数减1,如果是0就去掉,模拟一下就好了.
#include <bits/stdc++.h> //#define inf 0x3f3f3f3f #define endl '\n' #define int long long using namespace std; const int N = 2e3 + 10, mod = 1e9 +7; //typedef long long ll; typedef pair<int,int> PII; //queue<PII> q1; map<vector<int>, int > mp; //priority_queue <int,vector<int>,greater<int> > q2; int n,m,t,k; /* */ vector<int> a, b; void solve() { string s; cin >> s >> m; while(m--){ if(s.back() != '0'){ s[s.size() - 1] --; } else s.erase(s.size() - 1, 1); } cout << s << endl; } signed main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); int Ke_scholar = 1; //cin >> Ke_scholar ; while(Ke_scholar--) solve(); return 0; }
B. Two-gram
暴力枚举,每次取两个字母再循环找一遍,输出最多次数的即可.
#include <bits/stdc++.h> //#define inf 0x3f3f3f3f #define endl '\n' #define int long long using namespace std; const int N = 2e3 + 10, mod = 1e9 +7; //typedef long long ll; typedef pair<int,int> PII; //queue<PII> q1; map<vector<int>, int > mp; //priority_queue <int,vector<int>,greater<int> > q2; int n,m,t,k; /* */ vector<int> a, b; void solve() { cin >> n; string s; cin >> s; string ans ; int maxx = 0; for(int i = 0;i < s.size() - 1; i++){ string s1 = s.substr(i,2); int x = 0; for(int j = 0; j <s.size() - 1; j ++){ if(s.substr(j, 2) == s1) x ++; } if(x > maxx){ maxx = x; ans = s1; } } cout << ans << endl; } signed main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); int Ke_scholar = 1; //cin >> Ke_scholar ; while(Ke_scholar--) solve(); return 0; }
C. Less or Equal
有个很坑的点,结束了看题解我才知道,k = 0 的时候分两种,如果最小的元素不是1的话应该输出1才对,害,我还以为0代表没有比较的,直接输出-1.
m == n 和 m == 0时特判一下,其余排个序再判断m前后是否相等的就行.
#include <bits/stdc++.h> //#define inf 0x3f3f3f3f #define endl '\n' #define int long long using namespace std; const int N = 2e3 + 10, mod = 1e9 +7; //typedef long long ll; typedef pair<int,int> PII; //queue<PII> q1; map<vector<int>, int > mp; //priority_queue <int,vector<int>,greater<int> > q2; int n,m,t,k; /* */ vector<int> a, b; void solve() { cin >> n >> m; for(int i = 0;i < n; i++){ int x; cin >> x; a.push_back(x); } sort(a.begin(), a.end()); if(m == n){ cout << a.back() << endl; return ; } if(m == 0){ if(a.front() != 1) cout << 1 << endl; else cout << -1 << endl; return ; } if(a[m] == a[m - 1]){ cout << -1 << endl; } else cout << a[m - 1] << endl; } signed main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); int Ke_scholar = 1; //cin >> Ke_scholar ; while(Ke_scholar--) solve(); return 0; }
D. Divide by three, multiply by two
将能被3整除的数或者是两倍关系的数的下标建成一条单向边,然后dfs去搜一条到达n的线路即可,至于为什么不用a[i]的值去建边,因为数据太大会寄.像这种.
input
2 1000000000000000000 3000000000000000000
output
3000000000000000000 1000000000000000000
#include <bits/stdc++.h> #define endl '\n' #define int long long using namespace std; const int N = 110; //typedef long long ll; typedef pair<int,int> PII; //queue<PII> q1; map<vector<int>, int > mp; //priority_queue <int,vector<int>,greater<int> > q2; int n,m,t,k; /* */ bool vis[N]; int arr[N]; vector<int> v[N]; int a[N],ans[N]; void dfs(int val,int x){ ans[x] = a[val]; if(x >= n){ for(int i = 1;i <= n; i++) { cout << ans[i] << ' '; } return ; } for(auto i : v[val]) dfs(i, x + 1); return ; } void solve() { cin >> n; for(int i = 0; i < n ;i++){ cin >> a[i]; } for(int i = 0; i < n; i++){ for(int j = 0;j < n;j ++){ if(i == j) continue; if(a[i] == a[j] * 3 || a[i] * 2 == a[j]){ v[i].push_back(j); } } } for(int i = 0;i < n; i++){ dfs(i, 1); } } signed main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); int Ke_scholar = 1; //cin >> Ke_scholar; while(Ke_scholar--) { solve(); } return 0; }
E. Cyclic Components
将每条边的入度记录一下,两点的入度都是2的话就用并查集维护一下,判断是否成环.
#include <bits/stdc++.h> #define endl '\n' #define int long long using namespace std; const int N = 2e5 + 10; //typedef long long ll; typedef pair<int,int> PII; //queue<PII> q1; map<vector<int>, int > mp; //priority_queue <int,vector<int>,greater<int> > q2; int n,m,t,k; /* */ bool vis[N]; int arr[N]; int ans; vector<PII> edge; int sum[N]; int fa[N]; int find(int x){ if(fa[x] == x) return x; return fa[x] = find(fa[x]); } void add(int x, int y){ int dx = find(x); int dy = find(y); if(dx != dy) fa[dx] = dy; else ans ++; } void solve() { cin >> n >> m; for(int i = 0; i < m; i++){ int x, y; cin >> x >> y; edge.push_back({x, y}); sum[x] ++; sum[y] ++; } for(int i = 1; i <= n; i++) fa[i] = i; for(int i = 0;i < m; i++){ if(sum[edge[i].first] == 2 && sum[edge[i].second] == 2) add(edge[i].first, edge[i].second); } cout << ans << endl; } signed main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); int Ke_scholar = 1; //cin >> Ke_scholar; while(Ke_scholar--) { solve(); } return 0; }
F. Consecutive Subsequence
用map做动态规划,记录最大的连续上升序列的结尾的值(记为maxid),然后从arr数组后面搜,如果等于maxid就放入ans里,maxid--,最后输出ans即可
#include <bits/stdc++.h> #define endl '\n' #define int long long using namespace std; const int N = 2e5 + 10; //typedef long long ll; typedef pair<int,int> PII; //queue<PII> q1; map<int, int > mp; //priority_queue <int,vector<int>,greater<int> > q2; int n,m,t,k; /* */ bool vis[N]; int arr[N]; int ans; int dp[N]; void solve() { cin >> n; int maxx = 0, maxid; for(int i = 1; i <= n; i++){ cin >> arr[i]; mp[arr[i]] = max(mp[arr[i]], mp[arr[i] - 1] + 1); if(mp[arr[i]] > maxx) { maxx = mp[arr[i]]; maxid = arr[i]; } } cout << maxx << endl; vector<int> ams; for(int i = n; i > 0; i--){ if(arr[i] == maxid){ ams.push_back(i); maxid--; } } for(int i = ams.size() - 1; i >= 0; i--) cout << ams[i] << ' '; } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr);cout.tie(nullptr); int Ke_scholar = 1; //cin >> Ke_scholar; while(Ke_scholar--) solve(); return 0; }