A - Jiro
cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
int t = 3;
vector<char> c(4);
for(int i = 1; i <= 3; i ++ ) cin >> c[i];
if((c[1] == '>' && c[2] == '<') || (c[1] == '<' && c[3] == '>' && c[2] == '>')) cout << "A";
else if((c[2] == '>' && c[3] == '<') || (c[1] == '<' && c[2] == '<' && c[3] == '>')) cout << "C";
else cout << "B";
return 0;
}
B - Taro
cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<vector<char>> s(n + 1);
for(int i = 1; i <= m; i ++ ) {
int x;
cin >> x;
char c;
cin >> c;
if(c == 'F') cout << "No" << endl;
else {
if(s[x].empty()) cout << "Yes" << endl;
else cout << "No" << endl;
s[x].push_back(0);
}
}
return 0;
}
C - Make Isomorphic
问题:
思路:注意到n非常小,因此爆搜。g图中的点以一定结构排列,我们可以枚举h图中所有点以g图为板子的所有排列,例如g图中的第一个点,可以放h图中的任意一个点,之后再暴力枚举某种排列时刻点与点之间是否有边,以此来计算花费
代码:
cpp
#include <bits/stdc++.h>
using namespace std;
const int N = 10;
typedef long long ll;
int g[N][N], h[N][N];
int main() {
int n;
cin >> n;
vector<int> gr(n + 1);
for(int i = 1; i <= n; i ++ ) gr[i] = i;
int wg;
cin >> wg;
while(wg -- ) {
int a, b;
cin >> a >> b;
g[a][b] = 1;
}
int wh;
cin >> wh;
while(wh -- ) {
int a, b;
cin >> a >> b;
h[min(a, b)][max(a, b)] = 1;
}
vector<vector<int>> a((n + 1), vector<int>(n + 1));
for(int i = 1; i <= n; i ++ ) {
for(int j = i + 1; j <= n; j ++ ) {
cin >> a[i][j];
}
}
ll ans = 0x3f3f3f3f;
do {
ll res = 0;
for(int i = 1; i <= n; i ++ ) {
for(int j = i + 1; j <= n; j ++ ) {
int fir = min(gr[i], gr[j]);
int sec = max(gr[i], gr[j]);
if((!h[fir][sec] && g[i][j]) || (h[fir][sec] && !g[i][j])){
res += a[fir][sec];
}
}
}
ans = min(ans, res);
} while(next_permutation(gr.begin() + 1, gr.end()));
cout << ans;
return 0;
}
D - 1D Country
问题:
思路:前缀和。注意到范围很大有2e9,因此再加个离散化。唯一的坑点就是给定的询问中的点可能没有村庄,特判一下就好
代码:
cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
vector<pair<int, long long>> pos(n + 1);
map<int, int> ma;
for(int i = 1; i <= n; i ++ ) {
int x;
cin >> x;
pos[i].first = x;
ma[x] ++;
}
for(int i = 1; i <= n; i ++ ) {
int x;
cin >> x;
pos[i].second = x;
}
sort(pos.begin() + 1, pos.end());
for(int i = 1; i <= n; i ++ ) {
pos[i].second += pos[i - 1].second;
}
pos[0].first = -0x3f3f3f3f;
auto find = [&](int x) {
int l = 0, r = n;
while(l < r) {
int mid = l + r + 1 >> 1;
if(pos[mid].first <= x) l = mid;
else r = mid - 1;
}
return l;
};
int q;
cin >> q;
while(q -- ) {
int l, r;
cin >> l >> r;
if(ma[l]) {
cout << pos[find(r)].second - pos[find(l) - 1].second << endl;
}
else cout << pos[find(r)].second - pos[find(l)].second << endl;
}
//cout << find(2);
//cout << find(5);
return 0;
}
E I hate sigma problems
问题:
思路:翻译一下题目就是,对于任意一个数,判断该数在多少个区间内出现过。
因此只需要记录下某个数上一次出现的位置last,该数对答案的贡献就是(i - last) * (n - i + 1)
代码:
cpp
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
int n;
cin >> n;
vector<int> a(n + 1);
for(int i = 1; i <= n; i ++ ) cin >> a[i];
map<int, ll> ma;
ll ans = 0;
for(ll i = 1; i <= n; i ++ ) {
ans += (i - ma[a[i]]) * (n - i + 1);
ma[a[i]] = i;
}
cout << ans;
return 0;
}
F