目录
A - Weak Beats
tag:签到
题解:
如果偶数的位置是1就输出No,否则就是Yes。
// 加油昂!!!
// Problem: A - Weak Beats
// Contest: AtCoder - UNIQUE VISION Programming Contest 2023 Autumn(AtCoder Beginner Contest 323)
// URL: https://atcoder.jp/contests/abc323/tasks/abc323_a
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef double db;
const int N = 2e5 + 5, M = 1e9 + 7, mod = 998244353;
#define YES {cout<<"Yes"<<endl;return ;}
#define NO {cout<<"No"<<endl;return ;}
int n, m, k;
void solve()
{
string s;
cin >> s;
for (int i = 0; i < 16; i++)
{
if (i % 2 && s[i] == '1') NO
}
YES
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
//cin >> t;
while (t--)
solve();
return 0;
}
B - Round-Robin Tournament
tag:签到,排序
题解:
把每个人赢得场次记下来,然后排序即可。
// 加油昂!!!
// Problem: B - Round-Robin Tournament
// Contest: AtCoder - UNIQUE VISION Programming Contest 2023 Autumn(AtCoder Beginner Contest 323)
// URL: https://atcoder.jp/contests/abc323/tasks/abc323_b
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef double db;
const int N = 1e5 + 5, M = 1e9 + 7;
#define YES {cout<<"YES"<<endl;return ;}
#define NO {cout<<"NO"<<endl;return ;}
char c[110][110];
void solve()
{
int n;
cin >> n;
map<int,int> mp;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cin >> c[i][j];
if (i == j) continue;
if (c[i][j] == 'o')
{
mp[i]++;
}
else
{
mp[j]++;
}
}
}
vector<pair<int,int>> ans;
for (int i = 1; i <= n; i++)
{
ans.push_back({mp[i], n + 1 - i });
}
sort(ans.begin(),ans.end());
reverse(ans.begin(),ans.end());
for (auto x:ans) cout <<n + 1 - x.second << " ";
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
//cin >> t;
while (t--)
solve();
return 0;
}
C - World Tour Finals
tag:签到,排序
题解:
把每个人得到的分数存下来,再把他们没做出来的题目存下来,然后遍历他们每个人,如果没有最大值大,那么就把没做的问题中分数最多的先做了,因此我们还需要对没有做过的题目进行一遍排序,保证我们每次做的题目都是当前没做过的题目中最大的那一个。然后再计数得答案。
// 加油昂!!!
// Problem: C - World Tour Finals
// Contest: AtCoder - UNIQUE VISION Programming Contest 2023 Autumn(AtCoder Beginner Contest 323)
// URL: https://atcoder.jp/contests/abc323/tasks/abc323_c
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include <bits/stdc++.h>
using namespace std;
typedef double db;
const int N = 1e5 + 5, M = 1e9 + 7;
#define YES {cout<<"YES"<<endl;return ;}
#define NO {cout<<"NO"<<endl;return ;}
vector<int> ans[105];
void solve()
{
int n, m;
cin >> n >> m;
int maxx = 0;
vector<int> a(m +10), sum(m + 10);
for (int i = 1; i <= m; i++)
{
cin >> a[i];
}
for (int i = 1; i <= n; i++)
{
string s;
cin >> s;
s = "?" + s;
sum[i] = i;
for (int j = 1; j <= m; j++)
{
if (s[j] == 'o')
{
sum[i] += a[j];
}
else
{
ans[i].push_back(a[j]);
}
}
maxx = max(maxx,sum[i]);
}
for (int i = 1; i <= n; i++)
{
sort(ans[i].begin(),ans[i].end());
reverse(ans[i].begin(),ans[i].end());
int now = 0;
while (sum[i] < maxx && now < ans[i].size())
{
sum[i] += ans[i][now];
now++;
}
cout << now << "\n";
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
//cin >> t;
while (t--)
solve();
return 0;
}
D - Merge Slimes
tag:模拟
题解:
本题用一个map实现,从mp.begin()开始,假设当前键是x,如果他的值是大于1的,就将其除2并加到2*x上,一直进行这个操作,如果他的值是奇数,那么原来的值就变为1,统计出1的个数即可。
// 加油昂!!!
// Problem: D - Merge Slimes
// Contest: AtCoder - UNIQUE VISION Programming Contest 2023 Autumn(AtCoder Beginner Contest 323)
// URL: https://atcoder.jp/contests/abc323/tasks/abc323_d
// Memory Limit: 1024 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef double db;
const int N = 2e5 + 5, M = 1e9 + 7, mod = 998244353;
#define YES {cout<<"YES"<<endl;return ;}
#define NO {cout<<"NO"<<endl;return ;}
int n, m, k;
void solve()
{
cin >> n;
map<int,int> mp;
for (int i = 0; i < n; i++)
{
int x, y;
cin >> x >> y;
mp[x] += y;
}
int ans = 0;
auto now = mp.begin();
while (now != mp.end())
{
int a = 1;
int x = (*now).first, y = (*now).second;
if (y > 1) mp[2 * x] += y / 2;
if (y & 1) ans++;
now++;
}
cout << ans << "\n";
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
//cin >> t;
while (t--)
solve();
return 0;
}
E - Playlist
tag:背包,费马小定理求逆元
题解:
这个题不难看出是一个背包问题的变种,相当于要求的是对于一个背包刚好装满j体积的概率是多少,分析可知,答案肯定是在(x-t[0]+1,x)中,因为他是要求在(x+0.5)的时候正好在播放歌曲1,因此我们直接求出(x-t[0]+1,x)区间的和,然后再乘上(1/n),我们可以首先求出(1/n)的逆元,这样我们后面算出得到的答案就可直接进行计数。
// 加油昂!!!
// Problem: E - Playlist
// Contest: AtCoder - UNIQUE VISION Programming Contest 2023 Autumn(AtCoder Beginner Contest 323)
// URL: https://atcoder.jp/contests/abc323/tasks/abc323_e
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef double db;
const int N = 2e5 + 5, M = 1e9 + 7, mod = 998244353;
#define YES {cout<<"YES"<<endl;return ;}
#define NO {cout<<"NO"<<endl;return ;}
int n, m, x;
int dp[10005];
int t[1005];
int quick_mi(int a, int b, int p)
{
int ans = 1 % p;
while(b)
{
if (b & 1) (ans *= a) %= p;
(a *= a) %= p;
b >>= 1;
}
return ans;
}
void solve()
{
cin >> n >> x;
for (int i = 0; i < n; i++)
{
cin >> t[i];
}
int res = quick_mi(n, mod - 2, mod);
dp[0] = 1;
for (int j = 1; j <= x; j++)
{
for (int i = 0; i < n; i++)
{
if (j < t[i]) continue;
dp[j] = (dp[j] + dp[j - t[i]] * res) % mod;
}
}
int ans = 0;
for (int i = max(0ll, x - t[0] + 1); i <= x; i++)
{
ans = (ans + dp[i]) % mod;
}
cout << ans * res % mod << "\n";
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
//cin >> t;
while (t--)
solve();
return 0;
}
F - Push and Carry
tag:数学,分类讨论,思维
题解:
(推箱子这个游戏小时候应该都玩过吧)首先,我们想一下,假设我们不需要变换方位,即直接走过去不改变推箱子的方向就能将箱子推到点C,我们需要多少步呢?答案是AB点和BC点的曼哈顿距离之和-1。因为最后点A到的位置是C的旁边一格,所以需要-1,所以只要我们不用特地的改变x的方向,答案就是上面说的这个,那么改变了的该怎么算呢。所以我们这样思考,固定一下点AC的位置,让点C始终在点A的右上方,如果点C在A的下方,沿x轴对称,如果点C在A的左方,沿y轴对称。然后枚举B的位置,分类讨论。每次绕路我们是从正面到了侧面,那么所需的多的步数就是3-1,所以我们每多绕一次路,即要多走2步,最多只会绕两次路。所以我们只需要计算出他变换位置变了几次即可。如下图所示,我们可以分出9个区域(均不包含线段和端点)。我们先考虑这九个区域,假设在1区域上存在一点x,A的路线是先走到点x的左边,将点x推到与C同一直线上,然后再到点的上面去,将该点推到C处,这个过程中,点A共绕路了两次,所以答案是ans+4。有两个特殊的线段是不需要绕路的,即25中间的线段(不包括端点)和56中间的线段(不包括端点),因为这两个方向只需要A在前往C的过程中顺便推一下即可,不会改变A的位置。
其他部分的答案推导同理,可得如下图:
(箭头指向的方向代表该边和哪一个区域的值相等)
注:黑色线的两个非AC点的答案也是ans+2。
现在就是一个分类讨论,别忘了把点C确定在点A的右上角即可。
// 加油昂!!!
// Problem: F - Push and Carry
// Contest: AtCoder - UNIQUE VISION Programming Contest 2023 Autumn(AtCoder Beginner Contest 323)
// URL: https://atcoder.jp/contests/abc323/tasks/abc323_f
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef double db;
const int N = 2e5 + 5, M = 1e9 + 7, mod = 998244353;
#define YES {cout<<"YES"<<endl;return ;}
#define NO {cout<<"NO"<<endl;return ;}
int n, m, k;
void solve()
{
int xa, ya, xb, yb, xc, yc;
cin >> xa >> ya >> xb >> yb >> xc >> yc;
int ans = abs(xa - xb) + abs(ya - yb) + abs(xb - xc) + abs(yb - yc) - 1;
if (xa > xc)
{
xa = -xa;
xb = -xb;
xc = -xc;
}
if (ya > yc)
{
ya = -ya;
yb = -yb;
yc = -yc;
}
if (xb == xc && yb > ya && yb < yc || yb == yc && xb > xa && xb < xc);
else if ((xb <= xa && (yb > yc || yb < ya)) || (yb == ya && xb < xa))
{
ans += 4;
}
else if ((xb > xc && (yb > yc || yb < ya)) || (yb == ya && xb > xc))
{
ans += 4;
}
else ans += 2;
cout << ans << "\n";
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
//cin >> t;
while (t--)
solve();
return 0;
}