A - Jiro
题意
给你AB, AC, BC之间的大小关系,问你ABC的中位数是哪个
大概思路
考虑用最少的特征分别决定其中两种情况,剩下一种情况直接排除法就行
代码
void solve(){
std::string AB, AC, BC;
std::cin >> AB >> AC >> BC;
if (AB == BC) {
std::cout << 'B';
return;
} else if (AC != BC) {
std::cout << 'C';
return;
} else {
std::cout << 'A';
return;
}
}
B - Taro
题意
n个家庭,按时间线生娃,每生一个就问这个娃是不是“该家庭的第一个男孩?”
大概思路
水题,直接vector记录就行
(Q:为什么不用set?A:n都告诉你了,你还用set,嫌时间复杂度够用,非要挂个log是吗)
代码
void solve(){
int n, m ;
std::cin >> n >> m;
std::vector<bool> ok(n + 1);
while (m--) {
int id;
std::string s;
std::cin >> id >> s;
if (s == "M" && !ok[id]) {
std::cout << "Yes\n";
ok[id] = 1;
} else {
std::cout << "No\n";
}
}
}
C - Make Isomorphic
题意
给你两个图,一个模版图G,一个操作用图H,以及操作H的各个边时的代价矩阵。求使得图H同构于图G的最小操作代价和。
两个图同构当且仅当其中一个图的序号存在一个 排列 使得两个图完全相等。
大概思路
抽象的题,第一次ABC差点写不出C。题目数据范围特别小,$n \le 8$,那么我们直接暴力枚举节点的所有排列,判断是否删边或加边即可。
思路不难想,但是实现很有趣。
代码
void solve(){
int n;
std::cin >> n;
//=============数据读入=============//
std::vector<std::vector<bool>> G(n + 1, std::vector<bool>(n + 1)), H = G;
int gn;
std::cin >> gn;
for (int i = 0; i < gn; i++) {
int x, y;
std::cin >> x >> y;
G[x][y] = G[y][x] = 1;
}
int hn;
std::cin >> hn;
for (int i = 0; i < hn; i++) {
int x, y;
std::cin >> x >> y;
H[x][y] = H[y][x] = 1;
}
std::vector<std::vector<int>> a(n + 1, std::vector<int>(n + 1));
for (int i = 1; i <= n - 1; i++) {
for (int j = i + 1; j <= n; j++) {
std::cin >> a[i][j];
a[j][i] = a[i][j];
}
}
//=============主逻辑=============//
i64 ans = 2e18;
std::vector<int> to(n);
std::iota(to.begin(), to.end(), 0);
do {
i64 cost = 0;
for (int i = 1; i <= n - 1; i++) {
for (int j = i + 1; j <= n; j++) {
int X = to[i - 1] + 1;
int Y = to[j - 1] + 1;
if (H[i][j] ^ G[X][Y]) {//代码核心,当且仅当两个图这对边不一样时,才要进行修改操作
cost += a[i][j];
}
}
}
ans = std::min(ans, cost);
} while (std::next_permutation(to.begin(), to.end()));//经典next_permutation
std::cout << ans;
}
D - 1D Country
题意
$n$户人分别住在$x_i$位置,每户有$p_i$人,给出 $q$ 个,每次问住在 $[l,r]$区间的有多少人。
大概思路
树状数组板子题,树状数组秒了(你要硬是想写大线段树,那我也没办法)
代码
template<typename T>
struct BIT {
std::vector<T> C;
int n;
BIT(int n_) {
C.clear();
C.resize(n_ + 1);
n = n_;
}
BIT() {}
BIT(const BIT& bit) {
n = bit.n;
C = bit.C;
}
T getsum(int x) {//获取[1, x]的和 O(logn)
T s = 0;
while (x) {
s += C[x];
x -= (x &- x);
}
return s;
}
void add(int x, T key) {//单点增加x的值 O(logn)
while (x <= n) {
C[x] += key;
x += (x &- x);
}
}
};
void solve(){
int n;
std::cin >> n;
BIT<i64> bit(n + 1);
std::vector<std::pair<int, int>> a(n);
for (auto &[x, _] : a) std::cin >> x;
for (auto &[_, p] : a) std::cin >> p;
std::vector<int> x(n);
for (int i = 0; i < n; i++) {
x[i] = a[i].first;
bit.add(i + 1, a[i].second);
}
int m;
std::cin >> m;
while (m--) {
int l, r;
std::cin >> l >> r;
int L = std::lower_bound(x.begin(), x.end(), l) - x.begin();
int R = std::upper_bound(x.begin(), x.end(), r) - x.begin();
std::cout << bit.getsum(R) - bit.getsum(L) << "\n";
}
}