传送门
A Wrong Subtraction
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 200010;
int a[N], b[N];
void solve() {
int n, m;
cin >> n >> m;
for (int i = 0; i < m; i++) {
string s = to_string(n);
if (s[s.size() - 1] == '0')n /= 10;
else n--;
}
cout << n << endl;
}
int32_t main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int h_h;
//cin >> h_h;
h_h=1;
while (h_h--)solve();
return 0;
}
B Two-gram
数据范围较小,直接暴力枚举即可
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 200010;
int a[N], b[N];
void solve() {
int n;
string s;
cin >> n >> s;
int mx = 0;
string str;
for (int i = 0; i < n; i++) {
string s1 = s.substr(i, 2);
int ans = 0;
for (int j = 0; j < n; j++) {
if (s1 == s.substr(j, 2))ans++;
}
if (mx < ans) {
mx = ans;
str = s1;
}
}
cout << str << endl;
}
int32_t main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int h_h;
//cin >> h_h;
h_h = 1;
while (h_h--)solve();
return 0;
}
C Less or Equal
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 200010, M = 1e9;
int a[N], b[N];
map <int,int> mp;
void solve() {
int n, m;
cin >> n >> m;
for (int i = 0; i < n; i++)cin >> a[i], mp[a[i]]++;
sort(a, a + n);
int sum = 0;
//for(auto &[f,s]: mp)cout<<f<<' '<<s<<endl;
if (m == 0) {
if (a[0] == 1) {
cout << -1 << endl;
return;
} else {
cout << 1 << endl;
return;
}
}
for (auto &[f, s]: mp) {
sum += s;
if (sum == m) {
cout << f << endl;
return;
} else if (sum > m) {
cout << -1 << endl;
return;
}
}
}
int32_t main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int h_h;
//cin >> h_h;
h_h = 1;
while (h_h--)solve();
return 0;
}
D Divide by three, multiply by two
可以直接把所有满足条件的两个数字之间建一条单向边,因为保证一定有解,所以对每个点都跑一遍dfs,只要ans数组里的数达到n个,就输出并且退出程序即可。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 10010;
int h[N], e[N], ne[N], idx;
int n;
int edge[N];
bool vis[N];
vector<int> ans;
void add (int a,int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
void dfs(int u) {
if (ans.size() == n) {
for (auto i: ans)cout << i << ' ';
exit(0);
}
vis[u] = true;
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if (!vis[j]) {
vis[j] = true;
ans.push_back(edge[j]);
dfs(j);
ans.pop_back();
vis[j] = false;
}
}
}
int32_t main() {
memset(h, -1, sizeof h);
cin >> n;
for (int i = 0; i < n; i++)cin >> edge[i];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (edge[i] * 2 == edge[j] || edge[i] == edge[j] * 3) {
add(i, j);
}
}
}
for (int i = 0; i < n; i++) {
memset(vis, false, sizeof vis);
ans.clear();
ans.push_back(edge[i]);
dfs(i);
}
return 0;
}
这个题也可以使用拓扑序列来做,因为有解,一定可以保证有拓扑序列,然后跑一边拓扑序列即可
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 10010;
int h[N], e[N], ne[N], idx;
int n;
int edge[N];
bool vis[N];
vector<int> ans;
int indg[N];
void add (int a,int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
void topsort() {
queue<int> q;
for (int i = 0; i < n; i++) {
if (indg[i] == 0)q.push(i);
}
while (q.size()) {
auto t = q.front();
q.pop();
ans.push_back(edge[t]);
for (int i = h[t]; ~i; i = ne[i]) {
int j = e[i];
indg[j]--;
if (indg[j] == 0)q.push(j);
}
}
}
int32_t main() {
memset(h, -1, sizeof h);
cin >> n;
for (int i = 0; i < n; i++)cin >> edge[i];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (edge[i] * 2 == edge[j] || edge[i] == edge[j] * 3) {
add(i, j);
indg[j]++;
}
}
}
topsort();
for(auto i:ans)cout<<i<<' ';
return 0;
}
E Cyclic Components
题目要救求解一个单环,意思就是每条边的度为2,那么我们可以用dfs来找出答案,dfs的时候判断一下,只有没有被标记过并且度为2的才可以进行搜索,只要搜索过程中出现度不为2的边,就标记,只要出现了就代表不行,否则就让答案++
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N = 2000010;
int n, m;
int indg[N];
bool vis[N];
int h[N],e[N],ne[N],idx;
bool ok;
int ans;
void add(int a,int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
void dfs(int u) {
vis[u] = true;
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if (!vis[j]) {
if (indg[j] == 2)dfs(j);
else ok = false;
}
}
}
int32_t main() {
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
memset(h, -1, sizeof h);
cin >> n >> m;
while (m--) {
int a, b;
cin >> a >> b;
add(a, b);
add(b, a);
indg[a]++, indg[b]++;
}
for (int i = 1; i <= n; i++) {
if (!vis[i] && indg[i] == 2) {
ok = true;
dfs(i);
if (ok)ans++;
}
}
//for (int i = 1; i <= n; i++)cout << indg[i] << ' ';
//puts("");
cout << ans << endl;
return 0;
}
也可以使用并查集来维护连通性,先预处理每条边的度数,然后再遍历一遍,只要两个点不在一个集合并且度数都为2就合并,如果两个点在一个集合当中,说明这两条再连在一起就成环了,答案++
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N = 400010;
int n, m;
int indg[N];
bool vis[N];
int h[N],e[N],ne[N],idx;
bool ok;
int ans;
void add(int a,int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
void dfs(int u) {
vis[u] = true;
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if (!vis[j]) {
if (indg[j] == 2)dfs(j);
else ok = false;
}
}
}
int32_t main() {
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
memset(h, -1, sizeof h);
cin >> n >> m;
while (m--) {
int a, b;
cin >> a >> b;
add(a, b);
add(b, a);
indg[a]++, indg[b]++;
}
for (int i = 1; i <= n; i++) {
if (!vis[i] && indg[i] == 2) {
ok = true;
dfs(i);
if (ok)ans++;
}
}
//for (int i = 1; i <= n; i++)cout << indg[i] << ' ';
//puts("");
cout << ans << endl;
return 0;
}
F Consecutive Subsequence
这题就是一个最长上升子序列的题目,只不过要求更加严格,要求每一个都比前一个大1,我们可以在dp的过程中就记录最大长度以及所对应的最后一个数值,方便再最后输出下标,最后输出下标就倒着遍历一遍,把答案放进vector中,最后翻转一下即可
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 200010, M = 1e9;
map<int,int> dp;
int n;
int a[N];
int ans,pos;
void solve() {
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a[i];
dp[a[i]] = dp[a[i] - 1] + 1;
if (ans < dp[a[i]]) {
ans = dp[a[i]];
pos = a[i];
}
}
//cout << ans << ' ' << pos << endl;
//for (auto i: dp)cout << i.first << ' ' << i.second << endl;
//cout << endl;
vector<int> b;
cout << ans << endl;
for (int i = n - 1; i >= 0; i--) {
if (pos == a[i]) {
b.push_back(i + 1);
pos--;
}
}
reverse(b.begin(), b.end());
for (auto i: b)cout << i << ' ';
}
int32_t main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int h_h;
//cin >> h_h;
h_h = 1;
while (h_h--)solve();
return 0;
}