鼠鼠我又来了,这次知道D题思路,但是老是wa,同时有事也就没写完DE题,现在补了补
A - Overall Winner
给一个字符串s,包含了两个人比赛的结果,输出最终的结果
需要注意的是,如果两个人赢的场数一样,那么输出最先达到该场数的,这里拿一个标志表示一下
# include <bits/stdc++.h>
# define int long long
# define endl '\n'
# define x first
# define y second
# define INF 0x3f3f3f3f
# define pii pair<int, int>
# define uf(i, j, k) for (int i = j; i <= k; i ++)
# define df(i, j, k) for (int i = j; i >= k; i --)
# define mset(x, v) memset(x, v, sizeof x)
using namespace std;
void solve()
{
int n;
string s;
cin >> n >> s;
int a[2] {};
int f = 0;
for (auto c : s)
{
if (c == 'T')
{
a[0] ++;
if (a[0] > a[1]) f = 0;
}
else
{
a[1] ++;
if (a[1] > a[0]) f = 1;
}
}
if (a[0] > a[1]) cout << "T" << endl;
else if (a[0] == a[1])
{
cout << (f == 0 ? "T" : "A") << endl;
}
else cout << "A" << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
// cin >> t;
while (t --) solve();
return 0;
}
B- Fill the Gaps
给一个序列,构造出相邻元素绝对值为1的新序列,模拟一下
# include <bits/stdc++.h>
# define int long long
# define endl '\n'
# define x first
# define y second
# define INF 0x3f3f3f3f
# define pii pair<int, int>
# define uf(i, j, k) for (int i = j; i <= k; i ++)
# define df(i, j, k) for (int i = j; i >= k; i --)
# define mset(x, v) memset(x, v, sizeof x)
/*
@see
*/
using namespace std;
const int N = 110;
int a[N];
void solve()
{
int n;
cin >> n;
vector<int> ans;
int t;
cin >> t;
ans.push_back(t);
uf (i, 2, n)
{
int x = ans[ans.size() - 1];
cin >> t;
if (abs(x - t) != 1)
{
if (x > t)
{
df (i, x - 1, t)
{
ans.push_back(i);
}
}
else if (x == t)
{
ans.push_back(t + 1);
ans.push_back(x);
}
else
{
uf (i, x + 1, t)
{
ans.push_back(i);
}
}
} else ans.push_back(t);
}
for (auto x : ans) cout << x << " ";
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
// cin >> t;
while (t --) solve();
return 0;
}
C-AtCoder Cards
给两个长度相等的字符串a和b,判断两个字符串是否通过替换@
字符和重新排列后能够相等
- 记录两个字符串
@
的个数,记录字符串a的字符个数(哈希) - 遍历字符串b,记录b中不在字符串a的字符
- 最后a哈希中的剩余字符就用b中的
@
消除,b中剩余字符就用a中的@
消除,判断能否相互消除
# include <bits/stdc++.h>
# define int long long
# define endl '\n'
# define x first
# define y second
# define INF 0x3f3f3f3f
# define pii pair<int, int>
# define uf(i, j, k) for (int i = j; i <= k; i ++)
# define df(i, j, k) for (int i = j; i >= k; i --)
# define mset(x, v) memset(x, v, sizeof x)
/*
@see
*/
using namespace std;
bool check(char ch)
{
if (ch == 'a' || ch == 't' || ch == 'c' || ch == 'o' || ch == 'd' || ch == 'e' || ch == 'r')
return true;
return false;
}
void solve()
{
string a, b;
cin >> a >> b;
bool ok = true;
int mp[26] {};
int acnt = 0, bcnt = 0;
for (auto c : a)
{
if (c == '@') acnt ++;
mp[c - 'a'] ++;
}
vector<char> bt;
for (auto c : b)
{
if (c == '@') bcnt ++;
else
{
if (mp[c - 'a'] > 0) mp[c - 'a'] --;
else bt.push_back(c);
}
}
uf (i, 0, 25)
{
if (mp[i] > 0)
{
if (check(i + 'a')) bcnt -= mp[i];
else ok = false;
}
}
for (auto x : bt)
{
if (check(x)) acnt -= 1;
else ok = false;
}
ok = bcnt >= 0 && bcnt == acnt;
cout << (ok ? "Yes" : "No") << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
// cin >> t;
while (t --) solve();
return 0;
}
D - Bitmask
给一个包含1
0
?
的字符串s和一个整数n,?
可以替换成 1
或者 0
,求出替换后
≤
n
\le n
≤n 的最大值,如果没有输出-1
- 先求出已有的
01
的最小值,即?
全部替换成0
的值,这个值如果 > n > n >n,那么任何一个?
替换成1
都不能比 n n n 小 - 然后逐位枚举
?
, 判断这个替换成1
后的值会不会超过n,如果不会则将其替换 - 最终的答案就是题目要求的最大值
这里使用位运算需要注意 溢出, 还有
pow
也是会溢出!!!鼠鼠我就是因为这个一直wa,以为自己开了long long万事大吉
# include <bits/stdc++.h>
# define int long long
# define endl '\n'
# define x first
# define y second
# define INF 0x3f3f3f3f
# define pii pair<int, int>
# define uf(i, j, k) for (int i = j; i <= k; i ++)
# define df(i, j, k) for (int i = j; i >= k; i --)
# define mset(x, v) memset(x, v, sizeof x)
using namespace std;
int n;
string s;
void solve()
{
cin >> s >> n;
int t = 0, m = s.length();
int l = -1, r = m;
while (++ l < -- r) swap(s[l], s[r]);
auto get = [](int x)
{
int ans = 1;
while (x --) ans *= 2;
return ans;
};
uf (i, 0, m - 1) if (s[i] == '1') t += get(i);
if (t > n) t = -1;
else
{
df (i, m - 1, 0)
{
// cout << t << " ";
if (s[i] == '?' && (t + get(i)) <= n) t += get(i);
}
}
cout << t << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
// cin >> t;
while (t --) solve();
return 0;
}
E - Pac-Takahashi
问题简述:
- 给一个
H
∗
W
H*W
H∗W 网格,起初在起点
S
,要抵达终点G
,最多走T
步,要求在抵达终点的过程中尽可能多拿糖果o
,如果能抵达则输出最大糖果数,如果不能则输出-1
思路:
-
近似旅行家问题,从起点到终点,每个糖果看做一个顶点,中间通过糖果的顺序和数目不确定,我们可以用二进制枚举出通过糖果的个数(糖果个数最多只有18个),最后取能够到达终点的最大值即可
-
状态表示:
dp[i][j]
从起点开始,经过状态i
后, 抵达第j
个糖果 的最短距离(状态i
为经过的糖果) -
状态转移:
(吐槽一下csdn的markdown,渲染不出来公式)
- 我们先处理出每个糖果到其他点的最短距离(BFS)
- 然后类似旅行商的DP处理出从起点开始到其他糖果的最短距离
# include <bits/stdc++.h>
# define int long long
# define endl '\n'
# define x first
# define y second
# define INF 0x3f3f3f3f
# define pii pair<int, int>
# define vi vector<int>
# define vii vector<vi>
# define uf(i, j, k) for (int i = j; i <= k; i ++)
# define df(i, j, k) for (int i = j; i >= k; i --)
# define mset(x, v) memset(x, v, sizeof x)
using namespace std;
const int N = 310;
char g[N][N];
bool st[N][N];
int n, m, t;
int bx, by, ex, ey;
vector<pii> candy;
int d[] {0, 1, 0, -1, 0};
bool chmin(int &a, int b)
{
if (a > b)
{
a = b;
return true;
}
else return false;
}
//枚举(tx, ty)这个点到其他点的最短距离
vii bfs(int tx, int ty)
{
mset(st, false);
vii res(N, vi(N, INF));
res[tx][ty] = 0;
queue<pii> q;
q.push({tx, ty});
while (q.size())
{
auto cur = q.front(); q.pop();
int x = cur.x, y = cur.y;
if (st[x][y]) continue;
st[x][y] = true;
uf (i, 0, 3)
{
int dx = x + d[i], dy = y + d[i + 1];
if (dx < 1 || dx > n || dy < 1 || dy > m || g[dx][dy] == '#' || st[dx][dy]) continue;
if (chmin(res[dx][dy], res[x][y] + 1)) q.push({dx, dy});
}
}
return res;
}
void solve()
{
cin >> n >> m >> t;
uf (i, 1, n)
{
cin >> g[i] + 1;
uf (j, 1, m)
{
if (g[i][j] == 'S') bx = i, by = j;
if (g[i][j] == 'G') ex = i, ey = j;
if (g[i][j] == 'o') candy.push_back({i, j});
}
}
int cnt = candy.size();
vector<vii> dist(cnt);
uf (i, 0, cnt - 1) dist[i] = bfs(candy[i].x, candy[i].y); //处理每个糖果到每个点的最短路径
vii dp(1 << cnt, vi(cnt, INF));
uf (i, 0, cnt - 1) dp[1 << i][i] = dist[i][bx][by]; //初始化每个糖果到起点的路径,结合状态表示
int all = 1 << cnt;
uf (i, 1, all - 1)
{
uf (j, 0, cnt - 1)
{
if (dp[i][j] == INF) continue; //无法抵达j
uf (k, 0, cnt - 1)
{
if ((i >> k) & 1) continue; //k不在状态i里面,可以作为下一个目标
chmin(dp[i |(1 << k)][k], dp[i][j] + dist[j][candy[k].x][candy[k].y]);
}
}
}
int ans = -1;
vii none = bfs(bx, by); //先判断从起点直接走能不能抵达终点
if (none[ex][ey] <= t) ans = 0;
uf (i, 1, all - 1)
{
uf (j, 0, cnt - 1)
{
if (dp[i][j] + dist[j][ex][ey] <= t)
//从起点开始,经过集合i中(拿了i情况的糖果),最后在第j个糖果的最短距离 + 第j个糖果到终点的距离
{
int cur = 0;
uf (k, 0, cnt - 1) if (i >> k & 1) cur ++; //统计i情况中拿了多少糖果
ans = max(ans, cur);
}
}
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
// cin >> t;
while (t --) solve();
return 0;
}
毕竟我们只有一生这么长
要用力给人间留下些印象