ABC301 复盘
ABC301 复盘
[ABC301A] Overall Winner
思路解析:从头开始遍历字符串,遇到一个字符就给对应的一方加分,输出第一个胜场大于 \(\lceil n / 2\rceil\) 的一方。
#include<bits/stdc++.h>
using namespace std;
int n;
string str;
int main() {
cin >> n;
cin >> str;
int win = (int)ceil((double)n / 2);
int a = 0, t = 0;
for(int i = 0; i < n; i++) {
if(str[i] == 'A') a++;
else if(str[i] == 'T') t++;
if(a >= win) {
cout << "A";
return 0;
}
else if(t >= win) {
cout << "T";
return 0;
}
}
return 0;
}
[ABC301B] Fill the Gaps
思路解析:对于每两个相邻的数直接顺序输出它们之间的数即可
#include<bits/stdc++.h>
using namespace std;
int n;
int a[110];
int main() {
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> a[i];
}
for(int i = 1; i < n; i++) {
cout << a[i] << " ";
if(a[i] - a[i + 1] > 1) {
for(int j = a[i] - 1; j > a[i + 1]; j--) {
cout << j << " ";
}
}
else if(a[i] - a[i + 1] < -1) {
for(int j = a[i] + 1; j < a[i + 1]; j++) {
cout << j << " ";
}
}
}
cout << a[n];
return 0;
}
[ABC301C] AtCoder Cards
思路解析:先分别用一个 map 记录下两个字符串每个字母的出现次数,然后对于每一个出现次数不同的字母,判断是否是 atcoder 中的任意一个,如果是,则判断剩下的 @ 符够不够用。
#include<bits/stdc++.h>
using namespace std;
string s, t;
map<char, int> mps, mpt;
set<char> st;
set<char> atcoder;
bool check(char ch) {
return atcoder.find(ch) != atcoder.end();
}
void init() {
atcoder.insert('a');
atcoder.insert('t');
atcoder.insert('c');
atcoder.insert('o');
atcoder.insert('d');
atcoder.insert('e');
atcoder.insert('r');
}
int main() {
init();
cin >> s >> t;
for(int i = 0; i < s.size(); i++) {
mps[s[i]]++;
}
for(int i = 0; i < t.size(); i++) {
mpt[t[i]]++;
}
for(int i = 0; i < t.size(); i++) {
if(mpt[t[i]] != mps[t[i]]) {
st.insert(t[i]);
}
if(mpt[s[i]] != mps[s[i]]) {
st.insert(s[i]);
}
}
st.erase('@');
for(auto it : st) {
if(!check(it)) {
cout << "No";
return 0;
}
if(mpt[it] > mps[it]) {
mps['@'] -= mpt[it] - mps[it];
if(mps['@'] < 0) {
cout << "No";
return 0;
}
}
if(mpt[it] < mps[it]) {
mpt['@'] -= mps[it] - mpt[it];
if(mpt['@'] < 0) {
cout << "No";
return 0;
}
}
}
cout << "Yes";
return 0;
}
[ABC301D] Bitmask
思路解析:贪心 + 纯模拟,先把不是 ? 的值算出来,然后遍历每一个 ?,如果加上 ? 后的值 小于等于 \(n\) 就把答案加上 ? 对应位的值。
错因:切记这里的二进制是反向输入的,每一位的值是 \(2 ^ \left(n - i + 1 \right)\)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n;
string str;
int main() {
cin >> str;
ll x;
cin >> x;
n = x;
ll sum = 0;
for(int i = 0; i < str.size(); i++) {
if(str[i] == '1') {
sum += (ll)1 << (str.size() - i - 1); //切记反向求
}
}
if(sum > n) {
cout << "-1";
return 0;
}
for(int i = 0; i < str.size(); i++) {
if(str[i] == '?') {
ll temp = ((ll)1 << (str.size() - i - 1));
if(sum + temp <= n) {
sum += temp;
}
}
}
cout << sum;
return 0;
}
[ABC301E] Pac-Takahashi
思路解析:注意到猴子数小于等于18,可以想到状压dp,加上起点和终点总共20个点正好符合状压dp的要求。先用 \(n\) 次 dfs 求出每两个猴子之间或到终点和起点的距离,若起点到终点的距离就 大于 \(t\) 那就直接输出 -1 然后返回,之后就做常规状压dp,最后对于每一种状态判断时间是否足够,若足够就统计抓到的猴子数求 \(max\)
__builtin_popcount(i) 可以用来求 i 的二进制中 1 的个数
#include<bits/stdc++.h>
using namespace std;
#define PII pair<int, int>
#define fir first
#define sec second
int n, m, t;
char ch[310][310];
int sx, sy, gx, gy;
int d[310][310];
int dx[4] = {0, 0, -1, 1};
int dy[4] = {-1, 1, 0, 0};
vector< PII > v;
int dis[30][30];
int sv, gv;
int f[2000010][30];
bool check(int x, int y) {
return x > 0 && x <= n && y > 0 && y <= m;
}
void bfs(int xx, int yy) {
queue< PII > q;
q.push({xx, yy});
memset(d, 0x3f, sizeof(d));
d[xx][yy] = 0;
while(!q.empty()) {
int x = q.front().fir, y = q.front().sec;
q.pop();
for(int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if(check(nx, ny) && ch[nx][ny] != '#' && d[nx][ny] > d[x][y] + 1) {
d[nx][ny] = d[x][y] + 1;
q.push({nx, ny});
}
}
}
}
int main() {
cin >> n >> m >> t;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
cin >> ch[i][j];
if(ch[i][j] == 'S') {
sx = i;
sy = j;
v.push_back({i, j});
sv = v.size() - 1;
}
else if(ch[i][j] == 'G') {
gx = i;
gy = j;
v.push_back({i, j});
gv = v.size() - 1;
}
else if(ch[i][j] == 'o') {
v.push_back({i, j});
}
}
}
swap(v[sv], v[0]);
sv = 0;
swap(v[gv], v[v.size() - 1]);
gv = v.size() - 1;
for(int i = 0; i < v.size(); i++) {
int xx = v[i].fir, yy = v[i].sec;
bfs(xx, yy);
for(int j = 0; j < v.size(); j++) {
dis[i][j] = d[v[j].fir][v[j].sec];
}
}
// cout << sv << " " << gv << " " << dis[sv][gv] << "\n";
if(dis[sv][gv] > t) {
cout << "-1";
return 0;
}
memset(f, 0x3f, sizeof(f));
f[1][0] = 0;
for(int i = 1; i < (1 << v.size()); i++) {
if(i & 1) {
for(int j = 0; j < v.size(); j++) {
if((i >> j) & 1) {
for(int k = 0; k < v.size(); k++) {
if((i >> k) & 1) {
f[i][j] = min(f[i][j], f[i ^ (1 << j)][k] + dis[k][j]);
}
}
}
}
}
}
int ans = 0;
for(int i = 1; i < (1 << v.size()); i++) {
if((i & 1) && ((i >> (v.size() - 1)) & 1)) {
if(f[i][v.size() - 1] <= t) {
ans = max(ans, __builtin_popcount(i) - 2);
}
}
}
cout << ans;
return 0;
}

浙公网安备 33010602011771号