A.Made Up
思路:先将 b c [ i ] b_{c[i]} bc[i]处理好存到 m a p map map里面,再遍历 a a a来查询是否存在即可
int n; cin >> n;
vector<int> a(n + 1), b(n + 1), c(n + 1);
for (int i = 1; i <= n; i ++) cin >> a[i];
for (int i = 1; i <= n; i ++) cin >> b[i];
for (int i = 1; i <= n; i ++) cin >> c[i];
map<int, int> mp;
for (int i = 1; i <= n; i ++) {
int j = c[i];
if (j <= n) mp[b[j]] ++;
}
int ans = 0;
for (int i = 1; i <= n; i ++) {
if (mp.count(a[i])) ans += mp[a[i]];
}
cout << ans << '\n';
B.H and V
思路:枚举每一行和每一列染成红色还是保持原样,直接二进制枚举验证答案就行
int h, w, k;
char g[10][10], a[10][10];
bool check(int x, int y) {
for (int i = 1; i <= h; i ++) {
for (int j = 1; j <= w; j ++) {
a[i][j] = g[i][j];
}
}
// debug2(x, y);
for (int i = 0; i < h; i ++) {
if (x >> i & 1) {
for (int j = 1; j <= w; j ++) a[i + 1][j] = 'r';
}
}
for (int i = 0; i < w; i ++) {
if (y >> i & 1) {
for (int j = 1; j <= h; j ++) a[j][i + 1] = 'r';
}
}
int cnt = 0;
for (int i = 1; i <= h; i ++) {
for (int j = 1; j <= w; j ++) {
cnt += (a[i][j] == '#');
}
}
return cnt == k;
}
void solve() {
cin >> h >> w >> k;
for (int i = 1; i <= h; i ++) {
for (int j = 1; j <= w; j ++) {
cin >> g[i][j];
}
}
int ans = 0;
for (int i = 0; i < (1 << h); i ++) {
for (int j = 0; j < (1 << w); j ++) {
if (check(i, j)) {
// debug2(i, j);
ans ++;
}
}
}
cout << ans << '\n';
}
D.Sum of Divisors
思路:这个题可以直接求每个数的因子数量,整体的复杂度是 O ( n l o g n ) O(nlogn) O(nlogn),调和及数的复杂度,正解就是每个因子的数量是一个等差数列,最后推出来一个公式,后面再说
void solve() {
int n; cin >> n;
vector<int> f(n + 1);
for (int i = 1; i <= n; i ++ ) {
for (int j = i; j <= n; j += i ) {
f[j] ++ ;
}
}
int res = 0;
for (int i = 1; i <= n; i ++ ) res += f[i] * i;
cout << res;
}
E.Red and Green Apples
思路:先把绿色和红色苹果那尽可能大的放到优先队列里面,如何将无色的苹果从小到大排序遍历,将能替换的全部替换
void solve() {
int x, y, a, b, c;
cin >> x >> y >> a >> b >> c;
vector<int> p(a), q(b), r(c);
for (int i = 0; i < a; i ++) cin >> p[i];
for (int i = 0; i < b; i ++) cin >> q[i];
for (int i = 0; i < c; i ++) cin >> r[i];
sort(p.rbegin(), p.rend());
sort(q.rbegin(), q.rend());
sort(r.begin(), r.end());
priority_queue<int, vector<int>, greater<int>> Q;
for (int i = 0; i < x; i ++) Q.push(p[i]);
for (int i = 0; i < y; i ++) Q.push(q[i]);
for (int i = 0; i < c; i ++) {
if (r[i] > Q.top()) {
Q.pop();
Q.push(r[i]);
}
}
int ans = 0;
while (Q.size()) ans += Q.top(), Q.pop();
cout << ans << '\n';
}
F. Rem of Sum is Num
思路:把题目意思转化为公式 ( S r − S l − 1 ) % k = r − ( l − 1 ) (S_r - S_{l-1})\%k=r-(l -1) (Sr−Sl−1)%k=r−(l−1),把这个公式两边移项得: ( S r − r ) % k = ( S l − 1 − ( l − 1 ) ) % k (S_r - r)\%k=(S_{l - 1} - (l - 1)) \% k (Sr−r)%k=(Sl−1−(l−1))%k,因此,我们先把计算出所有得 ( S i − i ) % k (S_i - i)\%k (Si−i)%k,用 m a p map map存下来,然后用一个类似于滑动窗口的思想,动态维护 k k k个数,当滑窗内的数字超过 k k k个时。将首的数字的贡献减去
void solve() {
int n, k; cin >> n >> k;
vector<int> a(n + 1), s(n + 1);
for (int i = 1; i <= n; i ++) {
cin >> a[i];
s[i] = s[i - 1] + a[i];
}
map<int, int> mp;
mp[0] ++;
int ans = 0;
for (int i = 1; i <= n; i ++) {
int x = (s[i] - i) % k;
if (i >= k) mp[(s[i - k] - i + k) % k] --;
ans += mp[x];
mp[x] ++;
}
cout << ans << '\n';
}
G. Keep Connect
思路:待补