#链接 https://atcoder.jp/contests/abc215/tasks
A 题
链接
https://atcoder.jp/contests/abc215/tasks/abc215_a
题解
签到水题。 给一个字符串,判断是否是 Hello,World!。
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> PLL;
const LL INF=4e18;
const int MAXN=1e6+10;
int main() {
#if 0
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#endif
#if 0
freopen("00.in", "r", stdin);
freopen("00.out", "w", stdout);
#endif
string s;
getline(cin, s);
if (s=="Hello,World!") {
cout<<"AC\n";
} else {
cout<<"WA\n";
}
return 0;
}
B 题
链接
https://atcoder.jp/contests/abc215/tasks/abc215_b
题解
给一个
n
n
n,找最大的整数
k
k
k,满足
2
k
≤
n
2^k \leq n
2k≤n。 由于本题的
n
n
n 很小,只有
1
0
18
10^{18}
1018,因此可以使用暴力求解。
AC 代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> PLL;
const LL INF=4e18;
const int MAXN=1e6+10;
int main() {
#if 1
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#endif
#if 0
freopen("00.in", "r", stdin);
freopen("00.out", "w", stdout);
#endif
LL n;
cin>>n;
LL k=0;
LL ans=1;
while (ans<=n) {
k++;
ans*=2;
}
cout<<k-1<<"\n";
return 0;
}
C题
链接
https://atcoder.jp/contests/abc215/tasks/abc215_c
题解
给一个字符串
S
S
S,求第
K
K
K 小的字典序字符串。 本题的
S
S
S 长度只有
8
8
8,也就意味着最多是
8
!
=
40
,
320
8!=40,320
8!=40,320 种答案。因此,我们只需要列出所有的全排列,然后输出第
K
K
K 小的即可。 最简单的方法就是使用 STL 的 next_permutation() 函数。当然也可以使用 dfs 来解。
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> PLL;
const LL INF=4e18;
const int MAXN=1e5+10;
string ans[MAXN];
int main() {
#if 1
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#endif
#if 0
freopen("00.in", "r", stdin);
freopen("00.out", "w", stdout);
#endif
string s;
LL K;
cin>>s>>K;
sort(s.begin(), s.end());
LL cnt=0;
do {
ans[++cnt]=s;
} while (next_permutation(s.begin(), s.end()));
cout<<ans[K]<<"\n";
return 0;
}
D题
链接
https://atcoder.jp/contests/abc215/tasks/abc215_d
题解
给
N
N
N 个正整数
A
1
,
?
A
2
,
?
…
,
?
A
N
A_1,\ A_2,\ \dots,\ A_N
A1?,?A2?,?…,?AN?,找出所有从
1
1
1 到
k
k
k,满足
gcd
(
A
i
,
k
)
=
1
\text{gcd}(A_i, k)=1
gcd(Ai?,k)=1。 本题要求找出任意一个
k
k
k 和数组
A
A
A 的所有元素互质。 如果本题使用暴力求解,即枚举所有的
1
~
m
1 \sim m
1~m 中的所有数据,使得其满足题目要求。但是由于
n
,
?
m
n,\ m
n,?m 的大小为
1
0
5
10^5
105,这个算法的时间复杂度为
O
(
m
?
n
)
O(m*n)
O(m?n),因此最大情况需要计算
1
0
5
?
1
0
5
=
1
0
10
10^5 *10^5=10^{10}
105?105=1010,这样的计算量即使是
2
2
2s 也是要超时的。 注意到本题的
A
i
A_i
Ai? 取值范围是
1
~
1
0
5
1 \sim 10^5
1~105,也就是说这个值域非常小。所以我们可以先用筛法筛出
1
0
5
10^5
105 中所有质数。然后再遍历
m
m
m。
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> PLL;
const int MAXN=1e5+10;
vector<bool> exist(MAXN, false);
vector<bool> ispri(MAXN, true);
int main() {
#if 1
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#endif
#if 0
freopen("00.in", "r", stdin);
freopen("00.out", "w", stdout);
#endif
LL n,m;
cin>>n>>m;
ispri[0]=ispri[1]=false;
for (LL i=1; i<=n; i++) {
LL val;
cin>>val;
exist[val]=true;
}
for (LL i=2; i<MAXN; i++) {
if (!ispri[i]) {
exist[i]=false;
continue;
}
for (LL j=i; j<MAXN; j+=i) {
ispri[j]=false;
if (exist[j]) {
exist[i]=true;
break;
}
}
}
vector<bool> possible(m+1, true);
possible[0]=false;
for (LL i=2; i<=m; i++) {
if (!exist[i]) {
continue;
}
for (LL j=i; j<=m; j+=i) {
possible[j]=false;
}
}
LL cnt=0;
for (LL i=1; i<=m; i++) {
if (possible[i]) {
cnt++;
}
}
cout<<cnt<<"\n";
for (LL i=1; i<=m; i++) {
if (possible[i]) {
cout<<i<<"\n";
}
}
return 0;
}
E题
链接
https://atcoder.jp/contests/abc215/tasks/abc215_e
题解
这题是竞赛后完成的。阅读完后,这题是一个 bit DP 题目。惨,bit DP 早就忘记了。还好,本题算 bit DP 的模板题,直接套用模板即可。 对应的状态方程如下:
d
p
[
i
]
[
u
]
[
j
]
=
d
p
[
i
?
1
]
[
u
]
[
j
]
dp[i][u][j]=dp[i-1][u][j]
dp[i][u][j]=dp[i?1][u][j] 其中:
i
i
i 表示竞赛的编号,
u
u
u 表示所有的集合,
j
j
j 表示竞赛的种类。
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN=1024;
LL dp[MAXN][MAXN][12];
const LL MOD=998244353;
int main(){
#if 1
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#endif
LL n;
string s;
cin>>n>>s;
for(LL i=1;i<=n;i++){
LL x=s[i-1]-'A';
for(LL u=0; u<MAXN;u++){
for(LL j=0;j<10;j++){
dp[i][u][j]=dp[i-1][u][j];
if(j==x){
dp[i][u][j]+=dp[i-1][u][j];
dp[i][u][j]%=MOD;
}
}
}
for(LL v=0;v<MAXN;v++){
if(v&(1<<x)){
continue;
}
for(LL j=0;j<10;j++){
dp[i][v|(1<<x)][x]+=dp[i-1][v][j];
dp[i][v|(1<<x)][x]%=MOD;
}
}
dp[i][(1<<x)][x]++;
dp[i][(1<<x)][x]%=MOD;
}
LL res=0;
for(LL u=0;u<MAXN;u++){
for(LL j=0;j<10;j++){
res+=dp[n][u][j];
res%=MOD;
}
}
cout << res << '\n';
return 0;
}
F题
链接
https://atcoder.jp/contests/abc215/tasks/abc215_f
题解
吐槽一下,F 题竟然比 E 题简单。 题目要求我们找所有最大问题的最小值,直接使用二分答案即可。 根据题目可知:
min
(
∣
x
i
?
y
i
∣
,
?
∣
x
j
?
y
j
∣
)
≥
K
→
∣
x
i
?
y
i
∣
≥
K
?&&?
∣
x
j
?
y
j
∣
≥
K
\text{min}(|x_i-y_i|,\ |x_j-y_j|) \geq K \rightarrow |x_i-y_i| \geq K\ \text{\&\&}\ |x_j-y_j| \geq K
min(∣xi??yi?∣,?∣xj??yj?∣)≥K→∣xi??yi?∣≥K?&&?∣xj??yj?∣≥K。
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> PLL;
const LL INF=4e18;
int main(){
#if 1
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#endif
LL n;
cin >> n;
vector<PLL> v(n);
for (LL i = 0; i < n; i++) {
cin >> v[i].first >> v[i].second;
}
sort(v.begin(), v.end());
LL ok = 0, ng = INF;
while(ng - ok > 1){
LL md = (ok + ng)/2;
queue<PLL> que;
bool able = false;
LL mi = INF, ma = 0;
for (auto p:v){
while(!que.empty()){
if(que.front().first > p.first - md) {
break;
}
mi = min(mi, que.front().second);
ma = max(ma, que.front().second);
que.pop();
}
if(mi <= p.second - md || ma >= p.second + md) {
able=true;
}
que.push(p);
}
if(able) {
ok = md;
} else {
ng = md;
}
}
cout << ok << endl;
return 0;
}
总结
我太难了,所有的东西都忘记了。人生艰难,连 ABC 都没法 AK 了。惨。
|