🚀欢迎来到本文🚀
🍉个人简介:陈童学哦,彩笔ACMer一枚。
🏀所属专栏: Atcoder
本文用于记录回顾总结本彩笔的解题思路便于加深理解。
比赛题目地址:AtCoder Beginner Contest 363
📢📢📢传送门
A - Piling Up
Problem Statement
In AtCoder, a user’s rating is given as a positive integer, and based on this value, a certain number of ^
is displayed. Specifically, when the rating is between
1
1
1 and
399
399
399, inclusive, the display rules are as follows:
- When the rating is between
1
1
1 and
99
99
99, inclusive,
^
is displayed once. - When the rating is between
100
100
100 and
199
199
199, inclusive,
^
is displayed twice. - When the rating is between
200
200
200 and
299
299
299, inclusive,
^
is displayed three times. - When the rating is between
300
300
300 and
399
399
399, inclusive,
^
is displayed four times.
Currently, Takahashi’s rating is
R
R
R. Here, it is guaranteed that
R
R
R is an integer between
1
1
1 and
299
299
299, inclusive.
Find the minimum increase in rating required for him to increase the number of displayed ^
.
It can be proved that under the constraints of this problem, he can increase the number of ^
without raising his rating to
400
400
400 or above.
解题思路
模拟即可。
AC代码
#include<bits/stdc++.h>
#define look(x) cout << #x << " == " << x << "\n"
using namespace std;
using i64 = long long;
const int N = 5e5 + 10;
const int MOD1 = 1e9 + 7;
const int MOD2 = 998244353;
void solve(){
int R;
cin >> R;
if(R >= 1 && R <= 99){
cout << 100 - R << "\n";
}else if(R >= 100 && R <= 199){
cout << 200 - R << "\n";
}else if(R >= 200 && R <= 299){
cout<< 300 - R << "\n";
}else if(R >= 300 && R <= 399){
cout << 400 - R << "\n";
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
while(t --){
solve();
}
return 0;
}
B - Japanese Cursed Doll
Problem Statement
There are
N
N
N people, and the current hair length of the
i
i
i-th person
(
1
≤
i
≤
N
)
(1 \leq i \leq N)
(1≤i≤N) is
L
i
L_i
Li.
Each person’s hair grows by
1
1
1 per day.
Print the number of days after which the number of people whose hair length is at least
T
T
T becomes
P
P
P or more for the first time.
If there are already
P
P
P or more people whose hair length is at least
T
T
T now, print
0
0
0.
解题思路
先判断为0的情况是否存在,不存在就输出第N - P + 1个人头发长度长到T所需要的天数。
AC代码
#include<bits/stdc++.h>
#define look(x) cout << #x << " == " << x << "\n"
using namespace std;
using i64 = long long;
const int N = 5e5 + 10;
const int MOD1 = 1e9 + 7;
const int MOD2 = 998244353;
void solve(){
int N,T,P;
cin >> N >> T >> P;
vector<int> a(N + 1);
int res = 0;
for(int i = 1;i <= N;i ++){
cin >> a[i];
if(a[i] >= T){
res ++;
}
}
if(res >= P){
cout << "0\n";
return;
}
sort(a.begin() + 1,a.end());
cout << T - a[N - P + 1] << "\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
while(t --){
solve();
}
return 0;
}
C - Avoid K Palindrome 2
Problem Statement
You are given a string S S S of length N N N consisting only of lowercase English letters.
Find the number of strings obtained by permuting the characters of S S S (including the string S S S itself) that do not contain a palindrome of length K K K as a substring.
Here, a string
T
T
T of length
N
N
N is said to “contain a palindrome of length
K
K
K as a substring” if and only if there exists a non-negative integer
i
i
i not greater than
(
N
−
K
)
(N-K)
(N−K) such that
T
i
+
j
=
T
i
+
K
+
1
−
j
T_{i+j} = T_{i+K+1-j}
Ti+j=Ti+K+1−j for every integer
j
j
j with
1
≤
j
≤
K
1 \leq j \leq K
1≤j≤K.
Here,
T
k
T_k
Tk denotes the
k
k
k-th character of the string
T
T
T.
解题思路
因为N很小,所有我们可以直接使用next_permutation
函数枚举所有的情况来计算不符合条件的情况。
需要注意的一点是使用next_permutation
前需要先sort
一下,不然会有问题。
复杂度为
10
!
10!
10!,为
3628800
3628800
3628800,也就是
3
e
6
3e6
3e6。
AC代码
#include<bits/stdc++.h>
#define look(x) cout << #x << " == " << x << "\n"
using namespace std;
using i64 = long long;
const int N = 5e5 + 10;
const int MOD1 = 1e9 + 7;
const int MOD2 = 998244353;
void solve(){
int N,K;
cin >> N >> K;
string s;
cin >> s;
//一定要记得先排序!!!!!
sort(s.begin(),s.end());
int ans = 0,res = 0;
do{
// look(s);
for(int i = 0;i < N - K + 1;i ++){
//是否符合条件的标记
int flag = 0;
int cnt = 1;
for(int j = i;j < i + K / 2;j ++){
if(s[j] != s[i + K - cnt]){
flag = 1;
break;
}
cnt ++;
}
if(!flag){
res ++;
break;
}
}
ans ++;
}while(next_permutation(s.begin(),s.end()));
// look(ans);
cout << ans - res << "\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
while(t --){
solve();
}
return 0;
}
D - Palindromic Number
Problem Statement
A non-negative integer
X
X
X is called a palindrome number if its decimal representation (without leading zeros) is a palindrome.
For example,
363
363
363,
12344321
12344321
12344321, and
0
0
0 are all palindrome numbers.
Find the N N N-th smallest palindrome number.
解题思路
AC代码
E - Sinking Land
Problem Statement
There is an island of size
H
×
W
H \times W
H×W, surrounded by the sea.
The island is divided into
H
H
H rows and
W
W
W columns of
1
×
1
1 \times 1
1×1 sections, and the elevation of the section at the
i
i
i-th row from the top and the
j
j
j-th column from the left (relative to the current sea level) is
A
i
,
j
A_{i,j}
Ai,j.
Starting from now, the sea level rises by
1
1
1 each year.
Here, a section that is vertically or horizontally adjacent to the sea or a section sunk into the sea and has an elevation not greater than the sea level will sink into the sea.
Here, when a section newly sinks into the sea, any vertically or horizontally adjacent section with an elevation not greater than the sea level will also sink into the sea simultaneously, and this process repeats for the newly sunk sections.
For each i = 1 , 2 , … , Y i=1,2,\ldots, Y i=1,2,…,Y, find the area of the island that remains above sea level i i i years from now.
解题思路
BFS加优先队列模拟一下即可解决。
AC代码
#include<bits/stdc++.h>
#define look(x) cout << #x << " == " << x << "\n"
using namespace std;
using i64 = long long;
const int N = 5e5 + 10;
const int MOD1 = 1e9 + 7;
const int MOD2 = 998244353;
int H,W,Y;
bool st[1010][1010];
int a[1010][1010];
int ans;
int dx[] = {-1,1,0,0};
int dy[] = {0,0,-1,1};
struct node{
int x,y,v;
bool operator > (const node &k) const{
return v > k.v;
}
};
void solve(){
cin >> H >> W >> Y;
priority_queue<node,vector<node>,greater<node>> q;
for(int i = 1;i <= H;i ++){
for(int j = 1;j <= W;j ++){
cin >> a[i][j];
if(i == 1 || j == 1 || i == H || j == W){
q.push({i,j,a[i][j]});
st[i][j] = true;
}
}
}
ans = H * W;
for(int i = 1;i <= Y;i ++){
while(!q.empty() && q.top().v <= i){
auto k = q.top();
q.pop();
ans --;
for(int i = 0;i < 4;i ++){
int kx = dx[i] + k.x;
int ky = dy[i] + k.y;
if(kx >= 1 && kx <= H && ky >= 1 && ky <= W){
if(!st[kx][ky]){
st[kx][ky] = true;
q.push({kx,ky,a[kx][ky]});
}
}
}
}
cout << ans << "\n";
}
for(int i = 1;i <= H;i ++){
for(int j = 1;j <= W;j ++){
st[i][j] = false;
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
while(t --){
solve();
}
return 0;
}
F - Palindromic Expression
Problem Statement
You are given an integer
N
N
N. Print a string
S
S
S that satisfies all of the following conditions. If no such string exists, print -1
.
-
S
S
S is a string of length between
1
1
1 and
1000
1000
1000, inclusive, consisting of the characters
1
,2
,3
,4
,5
,6
,7
,8
,9
, and*
(multiplication symbol). - S S S is a palindrome.
- The first character of S S S is a digit.
- The value of S S S when evaluated as a formula equals N N N.
解题思路
考虑dfs来枚举它的因子依次拆开,然后每次拆开后判断剩下的数是否为回文数。
是的话就依次输出前面枚举的因子,然后输出当前为回文数字的这个数,最后再把前面枚举到的每个因子从最后一个开始
每个都翻转后输出。
但这里需要注意的一个点是,当我们输入
169
169
169这个数时,它本身不是个回文数,但我们其实把它可以拆成
13
∗
13
13*13
13∗13这样,它
开起来好像是个回文串对吧,但是输入
169
169
169的时候输出的是
−
1
-1
−1,也就是说如果本身不是回文串的数,要把它拆成一个回文串时,这个回文串所包含的数字应该是个奇数,
13
∗
13
13*13
13∗13是两个数是偶数所以不是回文串。
但是我也没搞懂为啥
13
∗
13
13*13
13∗13不是回文串,就题目也没明确说明,有点不懂。
AC代码
#include<bits/stdc++.h>
#define look(x) cout << #x << " == " << x << "\n"
using namespace std;
using i64 = long long;
const int N = 2e5 + 10;
const int MOD1 = 1e9 + 7;
const int MOD2 = 998244353;
int f = 0;
i64 a[N];
//用来判断字符串是否符合条件和翻转字符
i64 judge(i64 x){
string s = to_string(x);
if(s.find('0') != -1){
return -1;
}
reverse(s.begin(),s.end());
i64 res = stoll(s);
return res;
}
void dfs(int k,i64 n){
//有符合条件的回文串
if(f == 1){
return;
}
//如果当前的数字为回文数字的话就输出答案。
if(judge(n) == n){
f = 1;
//先按顺序输出正序的
for(int i = 1;i < k;i ++){
cout << a[i] << "*";
}
cout << n;
//再倒叙输出反转的。
for(int i = k - 1;i >= 1;i --){
cout << "*" << judge(a[i]);
}
return;
}
//搜索枚举n的因子
for(int i = 2;i <= sqrt(n);i ++){
i64 x = judge(i);
//i首先要是n的因子,其次翻转后的i也就是x要是n/i的因子
if(n % i != 0 || n / i % x != 0){
continue;
}
a[k] = i;
//继续往下搜索
dfs(k + 1,n / i / x);
}
}
void solve(){
i64 n;
cin >> n;
dfs(1,n);
if(!f){
cout << "-1\n";
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
// cin >> t;
while(t --){
solve();
}
return 0;
}
G - Dynamic Scheduling
Problem Statement
You are given two sequences of length N N N: D = ( D 1 , D 2 , … , D N ) D=(D_1, D_2, \dots, D_N) D=(D1,D2,…,DN) and P = ( P 1 , P 2 , … , P N ) P=(P_1, P_2, \dots, P_N) P=(P1,P2,…,PN).
Process Q Q Q queries in the order they are given. Each query is given in the following format:
c x y
: Change D c D_c Dc to x x x and P c P_c Pc to y y y. Then, solve the following problem and print the answer.
There are N N N jobs numbered 1 1 1 to N N N.
Starting from today (consider this as day 1 1 1), you will choose and complete one job per day for N N N days.
If you complete job i i i on or before day D i D_i Di, you will receive a reward of P i P_i Pi. (If you do not complete it by day D i D_i Di, you get nothing.)
Find the maximum total reward you can achieve by choosing the optimal order of completing the jobs.