【MX-J15】梦熊J组·儿童节赛 题解
【MX-J15】梦熊J组·儿童节赛 题解
T1 叉叉学习数据类型
学习语法阶段的时候说过,超过对应数据范围的数就会溢出,我们利用这个特性就可以写:
#include <bits/stdc++.h>
#define ls u << 1
#define rs u << 1 | 1
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int MOD = 998244353;
const int N = 1e6 + 10;
void solve() {
string s; cin >> s;
int c1 = 0;
unsigned int c2 = 0;
long long c3 = 0;
unsigned long long c4 = 0;
int n = s.size();
if (s[0] == '-') {
bool flag1, flag2, flag3, flag4;
flag1 = flag3 = true;
flag2 = flag4 = false;
for (int i = 1; i < n; i ++ ) {
int now1 = c1 * 10 - (s[i] - '0');
long long now3 = c3 * 10 - (s[i] - '0');
if (now1 > c1) flag1 = false;
if (now3 > c3) flag3 = false;
c1 = now1, c3 = now3;
}
if (flag1) cout << "int\n";
if (flag3) cout << "long long\n";
cout << "string\n";
} else {
bool flag1, flag2, flag3, flag4;
flag1 = flag2 = flag3 = flag4 = true;
for (int i = 0; i < n; i ++ ) {
int now1 = c1 * 10 + s[i] - '0';
unsigned int now2 = c2 * 10 + s[i] - '0';
long long now3 = c3 * 10 + s[i] - '0';
unsigned long long now4 = c4 * 10 + s[i] - '0';
if (now1 < c1) flag1 = false;
if (now2 < c2) flag2 = false;
if (now3 < c3) flag3 = false;
if (now4 < c4) flag4 = false;
c1 = now1, c2 = now2, c3 = now3, c4 = now4;
}
if (flag1) cout << "int\n";
if (flag2) cout << "unsigned int\n";
if (flag3) cout << "long long\n";
if (flag4) cout << "unsigned long long\n";
cout << "string\n";
}
}
int main() {
ios::sync_with_stdio(false), cin.tie(0);
#ifndef ONLINE_JUDGE
freopen("1.in", "r", stdin);
freopen("1.out", "w", stdout);
#endif
int T = 1;
// cin >> T;
while (T -- ) solve();
return 0;
}
T2 叉叉学习位运算
读题后了解到,头尾的0可以随便添,但是1不可以,所以我们考虑把 \(b\) 的最低连续0给去掉,然后看看该串在 \(a\) 中是否出现过即可
#include <bits/stdc++.h>
#define ls u << 1
#define rs u << 1 | 1
using namespace std;
typedef unsigned long long ULL;
const int INF = 0x3f3f3f3f;
const int MOD = 998244353;
const int N = 1e6 + 10;
string ULL2String(ULL x) {
string ans = "";
while (x) {
ans.push_back(char('0' + (x & 1)));
x >>= 1;
}
if (ans == "") ans = "0";
reverse(ans.begin(), ans.end());
return ans;
}
void solve() {
ULL a, b; cin >> a >> b;
if (b == 0) {
cout << "Yes\n";
return ;
}
string ta = ULL2String(a);
string tb = ULL2String(b);
// cout << ta << ' ' << tb << endl;
while (tb.size() > 1 && tb.back() == '0') tb.pop_back();
for (int i = 0; i < ta.size(); i ++ ) {
string t = ta.substr(i, tb.size());
if (t == tb) {
cout << "Yes\n";
return ;
}
}
cout << "No\n";
}
int main() {
ios::sync_with_stdio(false), cin.tie(0);
#ifndef ONLINE_JUDGE
freopen("1.in", "r", stdin);
freopen("1.out", "w", stdout);
#endif
int T = 1;
cin >> T;
while (T -- ) solve();
return 0;
}
T3 叉叉学习与自我和解
模拟一下样例,我们发现一个问题:多连的线只要保证不会出现新的最短路就行了。
我们将给定的树的根记作 \(0\) ,那么众所周知,对于一棵树来说,任何一个点到树根的最短路就是深度。所以我们思考一个问题:如何连边会出现更短的路。
很明显,例如1点在第5层,那么当它往第4层连边都是没事的,但是往第3层,第2层连边就不行了。可以自己多举一些例子来帮助理解。
所以我们发现,对于每个点来说,可以连的边的个数就是同层的点数,以及下面和上面那一层的点数,当然要减去自己和已经连接的点。
然后我们的策略就是,这些边可以选也可以不选,设有 \(m\) 条边可以连,那么答案就是 \(2^m\) ,边数很多,需要用快速幂
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int N = 1e6 + 10;
vector<int> g[N];
int c[N];
int f[N];
void dfs(int u, int last, int dep) {
f[u] = dep;
c[dep] ++;
for (int v : g[u]) {
if (v == last) continue;
dfs(v, u, dep + 1);
}
}
LL q_pow(LL a, LL b) {
LL ans = 1;
while (b) {
if (b & 1) ans = ans * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return ans;
}
void solve() {
int n; cin >> n;
for (int i = 1; i < n; i ++ ) {
int u, v; cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(0, -1, 1);
LL ans = 0;
for (int i = 1; i < n; i ++ ) {
int now = f[i];
ans += c[now] - 1;
if (c[now + 1]) ans += c[now + 1] - (g[i].size() - 1);
if (c[now - 1]) ans += c[now - 1] - 1;
}
ans /= 2;
cout << q_pow(2, ans) << endl;
}
int main() {
ios::sync_with_stdio(false), cin.tie(0);
#ifndef ONLINE_JUDGE
freopen("1.in", "r", stdin);
freopen("1.out", "w", stdout);
#endif
int T = 1;
// cin >> T;
while (T -- ) solve();
return 0;
}
T4 叉叉学习魔法
题目要求求出在步数最小的前提下,使用魔法次数最少。
那我们先求出最小步数,然后在最短路转移的时候求出最少魔法次数即可。
由于边权只有0和1,所以可以使用双端队列BFS。
但是这道题会卡deque,所以需要手写deque
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<int, pair<int, int>> PIII;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int N = 5050 + 10;
char g[N][N];
int dis[N][N], f[N][N];
bool vis[N][N];
PII q[N * N * 2];
int he, ta;
int dx[] = {1, -1, 0, 0, 1, 1, -1, -1};
int dy[] = {0, 0, 1, -1, 1, -1, 1, -1};
void solve() {
int n, m; cin >> n >> m;
int stx, sty, edx, edy;
for (int i = 1; i <= n; i ++ ) {
for (int j = 1; j <= m; j ++ ) {
cin >> g[i][j];
if (g[i][j] == 'X') {
stx = i, sty = j;
} else if (g[i][j] == 'W') {
edx = i, edy = j;
}
}
}
he = N * N + 1, ta = N * N;
memset(dis, 0x3f, sizeof dis);
memset(f, 0x3f, sizeof f);
q[++ ta] = {stx, sty};
dis[stx][sty] = f[stx][sty] = 0;
while (he <= ta) {
PII t = q[he]; he ++;
int nx = t.first, ny = t.second;
vis[nx][ny] = true;
// cout << nx << ' ' << ny << ' ' << dis[nx][ny] << ' ' << f[nx][ny] << endl;
for (int i = 0; i < 8; i ++ ) {
int x = nx + dx[i], y = ny + dy[i];
if (vis[x][y]) continue;
if (x < 1 || x > n || y < 1 || y > m) continue;
if (g[x][y] == '#') continue;
if (dis[x][y] > dis[nx][ny] + (i < 4)) {
dis[x][y] = dis[nx][ny] + (i < 4);
if (i < 4) q[++ ta] = {x, y};
else q[-- he] = {x, y};
}
}
}
if (!vis[edx][edy]) {
cout << -1 << ' ' << -1 << endl;
return ;
}
memset(vis, 0, sizeof vis);
he = N * N + 1, ta = N * N;
q[++ ta] = {stx, sty};
while (he <= ta) {
PII t = q[he]; he ++;
int nx = t.first, ny = t.second;
if (vis[nx][ny]) continue;
for (int i = 0; i < 8; i ++ ) {
int x = nx + dx[i], y = ny + dy[i];
if (vis[x][y]) continue;
if (x < 1 || x > n || y < 1 || y > m) continue;
if (g[x][y] == '#') continue;
if (dis[x][y] == dis[nx][ny] + (i < 4)) {
if (f[x][y] > f[nx][ny] + (i >= 4)) {
f[x][y] = f[nx][ny] + (i >= 4);
if (i >= 4) q[++ ta] = {x, y};
else q[-- he] = {x, y};
}
}
}
}
cout << dis[edx][edy] << ' ' << f[edx][edy] << endl;
}
int main() {
ios::sync_with_stdio(false), cin.tie(0);
#ifndef ONLINE_JUDGE
freopen("1.in", "r", stdin);
freopen("1.out", "w", stdout);
#endif
int T = 1;
// cin >> T;
while (T -- ) solve();
return 0;
}

浙公网安备 33010602011771号