A.数位分解
用字符串输入后倒序输出即可
#include<bits/stdc++.h>
using namespace std;
int main() {
string s;
cin >> s;
int n = s.size();
for (int i = n - 1; i >= 0; i--) {
cout << s[i] << " ";
}
return 0;
}
B.大小写字母互换
用while(~scanf("%c", &c))
读入每个字符,判断读入的每个字符的类型,如果是大写字母则加上大小写ASCII码的差值,如果是小写字母则减去大小写ASCII码的差值,其他字符直接输出即可
#include<bits/stdc++.h>
using namespace std;
int main() {
char c;
char x = 'a' - 'A';
while (~scanf("%c", &c)) {
if (c >= 'a' && c <= 'z') cout << (char)(c - x);
else if (c >= 'A' && c <= 'Z') cout << (char)(c + x);
else cout << c;
}
return 0;
}
C.八进制转十进制
八进制转十进制的方法为:八进制数从右往左数(从0开始)第
i
i
i 位上的数字乘
8
i
8^i
8i 的总和
例如
(
114514
)
8
=
(
4
×
8
0
+
1
×
8
1
+
5
×
8
2
+
4
×
8
3
+
1
×
8
4
+
1
×
8
5
)
10
=
(
39244
)
10
(114514)_8=(4×8^0+1×8^1+5×8^2+4×8^3+1×8^4+1×8^5)_{10}=(39244)_{10}
(114514)8=(4×80+1×81+5×82+4×83+1×84+1×85)10=(39244)10
故我们将该数以字符串形式读入,翻转后遍历带入公式即可
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main() {
string s;
cin >> s;
reverse(s.begin(), s.end());
int n = s.size();
int ans = 0;
for (int i = 0; i < n; i++) {
ans += ((s[i] - '0') * (int)pow(8, i));
}
cout << ans;
return 0;
}
D.西西务者
按照题意读入
5
n
5n
5n 个数,排序后取中间
3
n
3n
3n 个数加和去平均值即可,本题输入输出数据量较大,使用 cin
cout
可能会超时
#include<bits/stdc++.h>
using namespace std;
#define int long long
int a[7000000];
signed main() {
int n;
scanf("%lld", &n);
for (int i = 0; i < 5 * n; i++) {
scanf("%lld", &a[i]);
}
sort(a, a + 5 * n);
int sum = 0;
for (int i = n; i < 4 * n; i++) {
sum += a[i];
}
double ans = 1.0 * sum / (3 * n);
printf("%.1lf", ans);
return 0;
}
E.睡大觉
用前缀和数组记录某个点一共睡了多长时间,然后对于每个
l
,
r
l,r
l,r ,分别二分找出从
0
0
0 到
l
l
l 、从
0
0
0 到
r
r
r 一共睡了多长时间,求二者差值即为
l
l
l 到
r
r
r 的睡眠时长
本题会卡 cin
cout
请使用 scanf
printf
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
int sum[200010], a[200010];
int Get(long long x){
int p = lower_bound(a + 1, a + n + 1, x) - a;
p--;
if(p & 1) return sum[p];
else return x - a[p] + sum[p];
}
signed main() {
scanf("%lld", &n);
for (int i = 1; i <= n; i++) {
cin >> a[i];
if (i & 1) sum[i] = sum[i - 1] + a[i] - a[i - 1];
else sum[i] = sum[i - 1];
}
int q;
scanf("%lld", &q);
while (q--) {
int l, r;
scanf("%lld%lld", &l, &r);
printf("%lld\n", Get(r) - Get(l));
}
return 0;
}
F.zzuacm 欢迎你
直接输出,Python一行秒了
print("hello zzuacm")
G.区间和的和
使用滑动窗口记录相邻的
k
k
k 个数的和,加到 ans
里以后将滑动窗口最左侧的值减去后加入下一个值,遍历整个数组即可
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main() {
int n, k;
cin >> n >> k;
vector<int> a(n + 5);
int ans = 0, tsum = 0;
for (int i = 0; i < n; i++) {
cin >> a[i];
if(i < k) tsum += a[i];
}
for (int i = k - 1; i < n; i++) {
ans += tsum;
tsum -= a[i - (k - 1)];
tsum += a[i + 1];
}
cout << ans;
return 0;
}
H.Sum of Maximum Weights
我们先将边按权值排序,这样每次处理的都是当前的最大权值
处理每一条边的时候,由于树,这条边的起点和终点一定不连通,所以我们设置两个组 U U U 和 V V V ,那么 U U U 组中任意成员到 V V V 组中任意成员的最大路径边权必为当前边的权值,设为 e e e,故可以写出 a n s + = s i z [ u ] × s i z [ v ] × e ans\ += siz[u] × siz[v]×e ans +=siz[u]×siz[v]×e ,然后将二组合并,之后对每条边考虑上述情况后即可得出答案
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e6 + 5;
const int M = N * 2;
int a[N], b[N];
int f[N];
int siz[N];
int Get(int u) {
return u == f[u] ? u : f[u] = Get(f[u]);
}
struct edge {
int u, v, e;
} e[N];
bool cmp(edge x, edge y) {
return x.e < y.e;
}
signed main() {
int n;
cin >> n;
for (int i = 1; i < n; i++) {
scanf("%lld %lld %lld", &e[i].u, &e[i].v, &e[i].e);
}
for (int i = 1; i <= n; i++) {
f[i] = i;
siz[i] = 1;
}
sort(e + 1, e + n, cmp);
int ans = 0;
for (int i = 1; i < n; i++) {
edge t = e[i];
int u = t.u, v = t.v, e = t.e;
u = Get(u), v = Get(v);
if (siz[u] < siz[v]) {
swap(u, v);
}
ans += siz[u] * siz[v] * e;
f[u] = v;
siz[v] += siz[u];
}
cout << ans << endl;
}
I.区间偶数和
直接输入,从第 l l l 个数开始判断是否为偶数,如果是偶数直接加入答案,一直判断到 r r r
#include<bits/stdc++.h>
using namespace std;
int main() {
int n, l, r;
cin >> n >> l >> r;
int ans = 0;
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
if (!(x & 1) && i >= l && i <= r) ans += x;
}
cout << ans;
return 0;
}
J.矩阵
长得很像这道题,甚至比他简单一点兴趣的同学可以做一下
当
n
n
n 为偶数时,我们不难发现对于矩阵中左上角的的数字(即
i
≤
n
/
2
,
j
≤
n
/
2
i \leq n / 2,j \leq n/2
i≤n/2,j≤n/2 时)
m
p
[
i
]
[
j
]
mp[i][j]
mp[i][j] 在旋转三次以后对应的位置分别在
m
p
[
j
]
[
n
−
i
+
1
]
,
m
p
[
n
−
i
+
1
]
[
n
−
j
+
1
]
,
m
p
[
n
−
i
+
1
]
[
j
]
mp[j][n-i+1],mp[n-i+1][n-j+1],mp[n-i+1][j]
mp[j][n−i+1],mp[n−i+1][n−j+1],mp[n−i+1][j] 这三个位置,所以我们只需要控制这四个位置的数字相同,将变成相同的数所需要的操作次数加入 ans
即可
若 n n n 为奇数,则还需要加上行和列中间的两条
#include<bits/stdc++.h>
using namespace std;
#define int long long
char mp[110][110];
signed main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> mp[i][j];
mp[i][j] = mp[i][j] - '0';
}
}
int ans = 0;
for (int i = 1; i <= n / 2; i++) {
for (int j = 1; j <= n / 2; j++) {
int cnt = mp[i][j] + mp[j][n - i + 1] + mp[n - j + 1][i] + mp[n - i + 1][n - j + 1];
ans += min(cnt, 4 - cnt);
}
}
if (n & 1) {
for (int i = 1; i <= (n + 1) / 2; i++) {
int j = (n + 1) / 2;
int cnt = mp[i][j] + mp[j][n - i + 1] + mp[n - j + 1][i] + mp[n - i + 1][n - j + 1];
ans += min(cnt, 4 - cnt);
}
}
cout << ans << endl;
return 0;
}
K.模拟类问题
开一个二维数组记录两人的关系,若 i i i 与 j j j 相邻,则 f [ i ] [ j ] = 1 f[i][j]=1 f[i][j]=1 ,然后枚举每一对人看他们是否曾经挨着即可
#include<bits/stdc++.h>
using namespace std;
int a[60], f[60][60];
int main() {
int n, m;
cin >> n >> m;
while (m--) {
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 2; i <= n; i++) {
f[a[i]][a[i - 1]] = f[a[i - 1]][a[i]] = 1;
}
}
int ans = 0;
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
ans += (f[i][j] == 0);
}
}
cout << ans;
return 0;
}
L.找最大值
定义变量 mx
初始化为
−
1
-1
−1 用来记录当前最大值,输入时判断该数是否为奇数,若为奇数就和当前最大值取max即可
#include<bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
int mx = -1;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
if (x & 1) mx = max(mx, x);
}
cout << mx;
return 0;
}