AtCoder Beginner Contest 363

🚀欢迎来到本文🚀
🍉个人简介:陈童学哦,彩笔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) (1iN) 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) (NK) such that T i + j = T i + K + 1 − j T_{i+j} = T_{i+K+1-j} Ti+j=Ti+K+1j for every integer j j j with 1 ≤ j ≤ K 1 \leq j \leq K 1jK.
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 1313这样,它
开起来好像是个回文串对吧,但是输入 169 169 169的时候输出的是 − 1 -1 1,也就是说如果本身不是回文串的数,要把它拆成一个回文串时,这个回文串所包含的数字应该是个奇数, 13 ∗ 13 13*13 1313是两个数是偶数所以不是回文串。
但是我也没搞懂为啥 13 ∗ 13 13*13 1313不是回文串,就题目也没明确说明,有点不懂。

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.

在这里插入图片描述

解题思路

AC代码

  • 21
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈童学哦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值