A. Asia区域赛
读题目输出奖牌之和就行,我把冠亚军也记成奖牌了。。
#include <bits/stdc++.h>
#define LL long long
#define P pair<int, int>
#include <time.h>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, n) for (int i = a; i <= n; ++i)
const int maxn = 1001;
#define mid ((l + r) >> 1)
#define lc rt<<1
#define rc rt<<1|1
using namespace std;
const int mod = 1e9 + 7;
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int ans = 29 + 87 + 58 + 11 + 1 + 1;
cout << ans << endl;
return 0;
}
B. Asia区域制
二进制转化为十进制,当成字符串搞搞 “4位一并”
#include <bits/stdc++.h>
#define LL long long
#define P pair<int, int>
#include <time.h>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, n) for (int i = a; i <= n; ++i)
const int maxn = 1001;
#define mid ((l + r) >> 1)
#define lc rt<<1
#define rc rt<<1|1
using namespace std;
const int mod = 1e9 + 7;
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int T;
cin >> T;
map<int, char> mp;
mp[10] = 'a';
mp[11] = 'b';
mp[12] = 'c';
mp[13] = 'd';
mp[14] = 'e';
mp[15] = 'f';
while (T--) {
string s;
cin >> s;
string t;
int len = s.size();
int last = len % 4;
for (int i = 0; last && i < 4 - last; ++i) {
s = "0" + s;
}
len = s.size();
int tmp = 0;
int cnt = 0;
for (int i = 0; i < len; ++i) {
++tmp;
cnt = cnt * 2 + s[i] - '0';
if (tmp % 4 == 0) {
// cout << tmp << endl;
if (cnt <= 9) t += '0' + cnt;
else t += mp[cnt];
cnt = 0;
}
}
cout << t << endl;
}
return 0;
}
C. Asia区域宫
每行每列只有一个障碍,只有存在一条对角线才可能把起点封住,读入点的时候预处理每种对角线的点数,如果存在点数合理就是NO,否者就是曼哈顿距离
#include <bits/stdc++.h>
#define LL long long
#define P pair<int, int>
#include <time.h>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, n) for (int i = a; i <= n; ++i)
const int maxn = 10001;
#define mid ((l + r) >> 1)
#define lc rt<<1
#define rc rt<<1|1
using namespace std;
int n, m;
int sum[maxn];
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int T;
cin >> T;
while (T--) {
mem(sum, 0);
cin >> n >> m;
for (int i = 0, x, y; i < m; ++i) {
cin >> x >> y;
sum[x+y-1]++;
}
int flag = 1;
for (int i = 1; i <= n; ++i) {
if (sum[i] == i) flag = 0;
}
if (flag) cout << "Yes " << 2*n - 2 << endl;
else cout << "No\n";
}
return 0;
}
D. Asia区域阵
当时读题的时候感觉好难,数据给的很小,但是暴力的话感觉很难写,于是就放弃了。
补个暴力,枚举矩阵的起点然后计算以该点能扩展的最大矩阵,列扩展的时候需要标记,因为之后的列一定小于等于当前所能扩展的最小列
#include <bits/stdc++.h>
#define LL long long
#define P pair<int, int>
#include <time.h>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, n) for (int i = a; i <= n; ++i)
const int maxn = 1000001;
#define mid ((l + r) >> 1)
#define lc rt<<1
#define rc rt<<1|1
using namespace std;
char a[101][101];
int R[101][91], C[101][91];
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int T;
scanf("%d", &T);
while (T--) {
int n, m;
scanf("%d %d", &n, &m);
for (int i = 0; i < n; ++i)
scanf("%s", a[i]);
int ans = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
mem(R, 0);
mem(C, 0);
int c = m;
for (int p = i; p < n; ++p) {
for (int k = j; k < c; ++k) {
int t = a[p][k];
if (R[p][t] || C[k][t]) {
c = k;
break;
}
ans = max(ans, (p-i+1)*(k-j+1));
R[p][t] = 1;
C[k][t] = 1;
}
}
}
}
printf("%d\n", ans);
}
return 0;
}
E. Mo的游戏
统计每个字符出现的位置,然后for一遍,找最小的差(最小的差一定相邻)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
vector<int> g[1000];
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
string s;
cin >> s;
int len = s.size();
for (int i = 0; i < len; ++i) {
int t = s[i];
g[t].push_back(i);
}
for (int i = 'a'; i <= 'z'; ++i) {
if (g[i].empty()) continue;
int ll = g[i].size();
if (ll == 1) {
cout << char(i) << ":0" << endl;
}else {
int tmp = g[i][1] - g[i][0];
for (int j = 2; j < ll; ++j) {
tmp = min(tmp, g[i][j] - g[i][j-1]);
}
cout << char(i) << ":" << len - tmp << endl;
}
}
for (int i = 'A'; i <= 'Z'; ++i) {
if (g[i].empty()) continue;
int ll = g[i].size();
if (ll == 1) {
cout << char(i) << ":0" << endl;
}else {
int tmp = g[i][1] - g[i][0];
for (int j = 2; j < ll; ++j) {
tmp = min(tmp, g[i][j] - g[i][j-1]);
}
cout << char(i) << ":" << len - tmp << endl;
}
}
return 0;
}
F. Mo的极限
字符串处理统计次方和对应的系数,最后找最大的判断
- 分子上的系数可能全部为0
- 可能存在相同指数的多项式,需要去重
- 最简分数的分母是负数
- 最简分数的分母是1
#include <bits/stdc++.h>
#define LL long long
#define P pair<int, int>
#include <time.h>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, n) for (int i = a; i <= n; ++i)
const int maxn = 1001;
#define mid ((l + r) >> 1)
#define lc rt<<1
#define rc rt<<1|1
using namespace std;
const int mod = 1e9 + 7;
struct ac{
int d, x;
bool operator < (const ac &t) {
return x > t.x;
}
}a[maxn], b[maxn];
void solve(string s, int &d, int &x) {
int flag = 1;
int len = s.size();
if (s[0] == '-') flag = -1;
int now = 0;
if (s[0] == '+' || s[0] == '-') now = 1;
int xx;
for (int i = 0; i < len; ++i) {
if (s[i] == '^') {
xx = i + 1;
break;
}
}
int num = 0;
for (int i = now; s[i] != 'x'; ++i) {
num = num * 10 + s[i] - '0';
}
d = num * flag;
num = 0;
for (int i = xx; i < len; ++i) {
num = num * 10 + s[i] - '0';
}
x = num;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
string s, t, tmp;
cin >> s >> t;
int lens, lent;
int ls = s.size();
int lt = t.size();
int now = 1;
map<int,int> mp;
//处理第一个多项式
for (int i = 0; i < ls; ++i) {
if (i == ls-1 || (i && (s[i] == '+' || s[i] == '-'))) {
if (i == ls-1) tmp += s[i];
int d, x;
solve(tmp, d, x);
if (mp[x]) {//去重
a[mp[x]].d += d;
tmp = s[i];
continue;
}
mp[x] = now;
a[now].d = d;
a[now++].x = x;
tmp = s[i];
}else tmp += s[i];
}
mp.clear();
lens = now;
now = 1;
tmp = "";
// 处理第二个多项式
for (int i = 0; i < lt; ++i) {
if (i == lt-1 || (i && (t[i] == '+' || t[i] == '-'))) {
if (i == lt-1) tmp += t[i];
int d, x;
solve(tmp, d, x);
if (mp[x]) {
b[mp[x]].d += d;
tmp = t[i];
continue;
}
mp[x]=now;
b[now].d = d;
b[now++].x = x;
tmp = t[i];
}else tmp += t[i];
}
lent = now;
sort(a+1, a + lens+1);
sort(b+1, b + lent+1);
int n, m = -1, a0, b0;
for (int i = 1; i < lens; ++i) {
if (a[i].d != 0) {
a0 = a[i].d;
m = a[i].x;
break;
}
}
for (int i = 1; i < lent; ++i) {
if (b[i].d != 0) {
b0 = b[i].d;
n = b[i].x;
break;
}
}
if (n > m) cout << 0 << endl;
else if (n < m) cout << "oo\n";
else {
int tt = __gcd(abs(a0), abs(b0));
a0 /= tt;
b0 /= tt;
if (b0 < 0) {
b0 *= -1;
a0 *= -1;
}
if (b0 == 1) cout << a0 << endl;
else cout << a0 << "/" << b0 << endl;
}
return 0;
}
G. Mo的数学
容斥,初始化
a
n
s
=
n
!
ans = n!
ans=n!,然后筛m的素因子,
1
−
n
1-n
1−n中与
m
m
m互质的数一定不含有
m
m
m的素因子,容器奇数个素因子除掉,偶数个素因子乘上,每个素因子最多有
n
t
\frac{n}{t}
tn个
a
n
s
1
t
×
2
t
×
.
.
.
×
n
t
t
=
a
n
s
n
t
!
t
n
t
\frac{ans}{1t × 2t ×...×\frac{n}{t}t} = \frac{ans}{\frac{n}{t}!t^\frac{n}{t}}
1t×2t×...×tntans=tn!ttnans
a
n
s
×
1
t
×
2
t
×
.
.
.
×
n
t
t
=
a
n
s
×
n
t
!
t
n
t
ans ×{1t × 2t ×...×\frac{n}{t}t} = ans ×{\frac{n}{t}!t^\frac{n}{t}}
ans×1t×2t×...×tnt=ans×tn!ttn
#include <bits/stdc++.h>
#define LL long long
#define P pair<int, int>
#include <time.h>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, n) for (int i = a; i <= n; ++i)
const int maxn = 1000001;
#define mid ((l + r) >> 1)
#define lc rt<<1
#define rc rt<<1|1
using namespace std;
LL mod = 1e9 + 7;
LL jie[maxn];
LL exgcd(LL a, LL b, LL &x, LL &y) {
LL d = a;
if (b == 0) x = 1,y = 0;
else {
d = exgcd(b, a%b, y, x);
y -= a / b * x;
}
return d;
}
LL inv(LL a, LL mod) {
LL x, y;
LL d = exgcd(a, mod, x, y);
return (d == 1) ? ((x + mod) % mod) : -1;
}
LL pow(LL x, LL a) {
LL ans = 1;
while (a) {
if (a&1) ans = ans * x % mod;
x = x * x % mod;
a >>= 1;
}
return ans;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int n, m;
jie[1] = jie[0] = 1;
for (LL i = 2; i < maxn; ++i) {
jie[i] = jie[i-1] * i % mod;
}
while (cin >> n >> m) {
vector<LL> su;
for (LL i = 2; i * i <= m; ++i) {
if (m % i == 0) {
su.push_back(i);
while (m % i == 0) m /= i;
}
}
if (m > 1) su.push_back(m);
LL ans = jie[n];
int len = su.size();
for (int i = 1; i < (1<<len); ++i) {
int cnt = 0;
LL t = 1;
for (int j = 0; (1<<j) <= i; ++j) {
if (i & (1<<j)) {
cnt++;
t = t * su[j] % mod;
}
}
LL x = jie[n/t] * pow(t, n/t) % mod;
if (cnt & 1) ans = ans * inv(x, mod) % mod;
else ans = ans * x % mod;
}
cout << ans << endl;
}
return 0;
}
H. Mo的面积
只有两个矩形的矩形面积并,分类讨论相交矩形的长和宽
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
struct ac{
int a, b, c, d;
};
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
ac x, y;
cin >> x.a >> x.b >> x.c >> x.d;
cin >> y.a >> y.b >> y.c >> y.d;
if (x.a > y.a) swap(x, y);
int ans = 0;
ans = (x.c - x.a) * (x.d - x.b);
ans += (y.c - y.a) * (y.d - y.b);
int l;
if (y.a >= x.a && y.c <= x.c) l = y.c - y.a;
if (y.a > x.a && y.c > x.c && y.a < x.c) l = x.c - y.a;
if (y.a < x.a && y.c > x.a && y.c < x.c) l = y.c - x.a;
if (y.a <= x.a && y.c >= x.c) l = x.c - x.a;
if (y.c <= x.a || y.a >= x.c) l = 0;
int r;
if (y.b >= x.d || y.d <= x.b) r = 0;
if (y.d >= x.d && y.b <= x.b) r = x.d - x.b;
if (y.d <= x.d && y.b >= x.b) r = y.d - y.b;
if (y.d > x.b && y.b < x.b && y.d < x.d) r = y.d - x.b;
if (y.b > x.b && y.d > x.d && y.b < x.d) r = x.d - y.b;
ans -= l * r;
cout << ans << endl;
return 0;
}
J. 简单递归
f [ n ] = 2 f [ n − 1 ] + f [ n − 2 ] 2 f[n] = 2f[n-1]+\frac{f[n-2]}{2} f[n]=2f[n−1]+2f[n−2]
#include <bits/stdc++.h>
#define LL long long
#define P pair<int, int>
#include <time.h>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, n) for (int i = a; i <= n; ++i)
const int maxn = 105;
#define mid ((l + r) >> 1)
#define lc rt<<1
#define rc rt<<1|1
using namespace std;
int mod = 1e9 + 7;
LL f[1000006];
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int T;
cin >> T;
f[1] = f[2] = 1;
for (int i = 3; i <= 1000000; ++i) {
f[i] = (f[i-1] * 2 % mod) + (f[i-2] / 2 % mod);
f[i] %= mod;
}
while (T--) {
int n;
cin >> n;
cout << f[n] << endl;
}
return 0;
}
K. 高度期望
贪心把最小的树变成最大
#include <bits/stdc++.h>
#define LL long long
#define P pair<int, int>
#include <time.h>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, n) for (int i = a; i <= n; ++i)
const int maxn = 105;
#define mid ((l + r) >> 1)
#define lc rt<<1
#define rc rt<<1|1
using namespace std;
int a[100005];
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int n, m;
cin >> n >> m;
int sum = 0;
for (int i = 0; i < n; ++i) {
cin >> a[i];
sum += a[i];
}
sort(a, a + n);
int last = m * n - sum;
int ans = 0;
for (int i = 0; i < n && last > 0; ++i) {
ans++;
last -= 1000 - a[i];
}
cout << ans << endl;
return 0;
}
L. 最优规划
并查集先把存在的边搞到一次,剩下的边从最小的边权开始看是否要加上
#include <bits/stdc++.h>
#define LL long long
#define P pair<int, int>
#include <time.h>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, a, n) for (int i = a; i <= n; ++i)
const int maxn = 100001;
#define mid ((l + r) >> 1)
#define lc rt<<1
#define rc rt<<1|1
using namespace std;
int fa[maxn];
int find(int x) {
return (x == fa[x]) ? x : fa[x] = find(fa[x]);
}
int join(int x, int y) {
int fx = find(x);
int fy = find(y);
if (fx == fy) return 0;
if (fx > fy) swap(fx, fy);
fa[fy] = fx;
return 1;
}
struct ac{
LL u, v, d;
bool operator < (const ac &t) {
return d < t.d;
}
}a[maxn];
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int n, m, s;
cin >> n >> m >> s;
for (int i = 1; i <= n; ++i) fa[i] = i;
for (int i = 0, u, v, d; i < m; ++i) {
cin >> u >> v >> d;
join(u, v);
}
LL ans = 0;
for (int i = 0; i < s; ++i) {
cin >> a[i].u >> a[i].v >> a[i].d;
}
sort(a, a + s);
for (int i = 0; i < s; ++i) {
int u = a[i].u;
int v = a[i].v;
LL d = a[i].d;
int t = join(u, v);
if (t) ans += d;
}
int flag = 1;
for (int i = 1; i <= n && flag; ++i) {
if (find(i) != find(1)) flag = 0;
}
if (flag) cout << ans << endl;
else cout << "Concubines can't do it.\n";
return 0;
}