AtCoder Beginner Contest 298——A-D题讲解

蒟蒻来讲题,还望大家喜。若哪有问题,大家尽可提!

Hello, 大家好哇!本初中生蒟蒻讲解一下AtCoder Beginner Contest 298这场比赛的A-D题

今晚比赛动不动就是网页无法显示了,官方说是被DDOS攻击了,导致今晚不算分,好在不算分,在D题目翻车了,算法是对的,但折腾了好长时间。

===========================================================================================

A - Job Interview

原题

Problem Statement

Takahashi had a job interview.
You are given the number of interviewers, N N N, and a string S S S of length N N N representing the interviewers’ evaluations of him.

For each i = 1 , 2 , … , N i=1,2,\ldots,N i=1,2,,N, the i i i-th character of S S S corresponds to the i i i-th interviewer’s evaluation; o means Good, - means Fair, and x means Poor.
Takahashi will pass if both of the following conditions are satisfied, and fail otherwise.
At least one interviewer’s evaluation is Good.
No interviewer’s evaluation is Poor.
Determine whether Takahashi passes.

Constraints

1 ≤ N ≤ 100 1 \leq N \leq 100 1N100
S S S is a string of length N N N consisting of o, -, and x.

Input

The input is given from Standard Input in the following format:
N N N
S S S

Output

If Takahashi passes, print Yes; otherwise, print No.

Sample Input 1

4
oo–

Sample Output 1

Yes
The first and second interviewers’ evaluations are Good, and no interviewer’s evaluation is Poor, so he passes.

Sample Input 2

3

Sample Output 2

No
No interviewer’s evaluation is Good, so he fails.

Sample Input 3

1
o

Sample Output 3

Yes

Sample Input 4

100
ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooox

Sample Output 4

No
The 100 100 100-th interviewer’s evaluation is Poor, so he fails.

思路

就是如果有x直接输出No,如果没有x,且有一个及以上o,那么输出Yes,否则输出No。
时间复杂度: O ( n ) O(n) O(n)

代码

#include <iostream>
#include <cstring>
#include <algorithm>
#define endl '\n'
#define psb(i) push_back(i)
#define ppb() pop_back()
#define psf(i) push_front(i)
#define ppf() pop_front()
#define ps(i) push(i)
 
using namespace std;
 
typedef pair<int, int> PII;
 
inline int read()
{
    int w = 1, s = 0;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-') w = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar();
    
    return w * s;
}
 
int main()
{
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);
    
    int n;
    string s;
    
    cin >> n >> s;
    
    bool hy = 0, hn = 0;
    for (auto c : s)
    	if (c == 'o')
    		hy = 1;
    	else if (c == 'x')
    		hn = 1;
    		
    if (!hn && hy)
    	cout << "Yes" << endl;
    else
    	cout << "No" << endl;
    
    return 0;
}

B - Coloring Matrix

原题

Problem Statement

You are given N N N-by- N N N matrices A A A and B B B where each element is 0 0 0 or 1 1 1.

Let A i , j A_{i,j} Ai,j and B i , j B_{i,j} Bi,j denote the element at the i i i-th row and j j j-th column of A A A and B B B, respectively.

Determine whether it is possible to rotate A A A so that B i , j = 1 B_{i,j} = 1 Bi,j=1 for every pair of integers ( i , j ) (i, j) (i,j) such that A i , j = 1 A_{i,j} = 1 Ai,j=1.

Here, to rotate A A A is to perform the following operation zero or more times:
for every pair of integers ( i , j ) (i, j) (i,j) such that 1 ≤ i , j ≤ N 1 \leq i, j \leq N 1i,jN, simultaneously replace A i , j A_{i,j} Ai,j with A N + 1 − j , i A_{N + 1 - j,i} AN+1j,i.

Constraints

1 ≤ N ≤ 100 1 \leq N \leq 100 1N100
Each element of A A A and B B B is 0 0 0 or 1 1 1.
All values in the input are integers.

Input

The input is given from Standard Input in the following format:
N N N
A 1 , 1 A_{1,1} A1,1 A 1 , 2 A_{1,2} A1,2 … \ldots A 1 , N A_{1,N} A1,N
⋮ \vdots
A N , 1 A_{N,1} AN,1 A N , 2 A_{N,2} AN,2 … \ldots A N , N A_{N,N} AN,N
B 1 , 1 B_{1,1} B1,1 B 1 , 2 B_{1,2} B1,2 … \ldots B 1 , N B_{1,N} B1,N
⋮ \vdots
B N , 1 B_{N,1} BN,1 B N , 2 B_{N,2} BN,2 … \ldots B N , N B_{N,N} BN,N

Output

If it is possible to rotate A A A so that B i , j = 1 B_{i,j} = 1 Bi,j=1 for every pair of integers ( i , j ) (i, j) (i,j) such that A i , j = 1 A_{i,j} = 1 Ai,j=1, print Yes; otherwise, print No.

Sample Input 1

3
0 1 1
1 0 0
0 1 0
1 1 0
0 0 1
1 1 1

Sample Output 1

Yes
Initially, A A A is :
0 1 1
1 0 0
0 1 0
After performing the operation once, A A A is :
0 1 0
1 0 1
0 0 1
After performing the operation once again, A A A is :
0 1 0
0 0 1
1 1 0
Here, B i , j = 1 B_{i,j} = 1 Bi,j=1 for every pair of integers ( i , j ) (i, j) (i,j) such that A i , j = 1 A_{i,j} = 1 Ai,j=1, so you should print Yes.

Sample Input 2

2
0 0
0 0
1 1
1 1

Sample Output 2

Yes

Sample Input 3

5
0 0 1 1 0
1 0 0 1 0
0 0 1 0 1
0 1 0 1 0
0 1 0 0 1
1 1 0 0 1
0 1 1 1 0
0 0 1 1 1
1 0 1 0 1
1 1 0 1 0

Sample Output 3

No

思路

这道题我们其实就是将数组进行 90 ° 90° 90°翻转,我们可以新开一个临时数组C,然后是数组A的翻转数组,这里可以套题目给的公式 C i , j = A N + 1 − j , i C_{i, j} = A_{N + 1 - j,i} Ci,j=AN+1j,i,之后进行判断是否可行。因为转四个就又会转回来,所以我们最多只用转4次。
时间复杂度: O ( n 2 ) O(n^2) O(n2)

代码

#include <iostream>
#include <cstring>
#include <algorithm>
#define endl '\n'
#define psb(i) push_back(i)
#define ppb() pop_back()
#define psf(i) push_front(i)
#define ppf() pop_front()
#define ps(i) push(i)
 
using namespace std;
 
typedef pair<int, int> PII;
 
const int N = 1e2 + 10;
 
int n;
int a[N][N];
int b[N][N];
int c[N][N];
 
inline int read()
{
    int w = 1, s = 0;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-') w = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar();
    
    return w * s;
}
 
int main()
{
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);
    
    cin >> n;
    
    for (int i = 1; i <= n; i ++)
    	for (int j = 1; j <= n; j ++)
    		cin >> a[i][j];
    		
    for (int i = 1; i <= n; i ++)
    	for (int j = 1; j <= n; j ++)
    		cin >> b[i][j];
    		
    for (int op = 1; op <= 4; op ++)
    {
    	memcpy(c, a, sizeof a);
    	for (int i = 1; i <= n; i ++)
    		for (int j = 1; j <= n; j ++)
    			c[i][j] = a[n + 1 - j][i];
    	
    	bool yes = 1;
    	for (int i = 1; i <= n; i ++)
    		for (int j = 1; j <= n; j ++)
    			if (c[i][j] == 1 && b[i][j] != 1)
    			{
    				yes = 0;
    				break;
    			}
    			
    	if (yes)
    	{
    		cout << "Yes" << endl;
    		return 0;
    	}
    	
    	memcpy(a, c, sizeof c);
    }
    
    cout << "No" << endl;
    
    return 0;
}

C - Cards Query Problem

原题

Problem Statement

We have N N N boxes numbered 1 1 1 to N N N that are initially empty, and an unlimited number of blank cards.

Process Q Q Q queries in order. There are three kinds of queries as follows.
1 i j  ⁣ : \colon : Write the number i i i on a blank card and put it into box j j j.
2 i  ⁣ : \colon : Report all numbers written on the cards in box i i i, in ascending order.
3 i  ⁣ : \colon : Report all box numbers of the boxes that contain a card with the number i i i, in ascending order.
Here, note the following.
In a query of the second kind, if box i i i contains multiple cards with the same number, that number should be printed the number of times equal to the number of those cards.
In a query of the third kind, even if a box contains multiple cards with the number i i i, the box number of that box should be printed only once.

Constraints

1 ≤ N , Q ≤ 2 × 1 0 5 1 \leq N, Q \leq 2 \times 10^5 1N,Q2×105
For a query of the first kind:
1 ≤ i ≤ 2 × 1 0 5 1 \leq i \leq 2 \times 10^5 1i2×105
1 ≤ j ≤ N 1 \leq j \leq N 1jN
For a query of the second kind:
1 ≤ i ≤ N 1 \leq i \leq N 1iN
Box i i i contains some cards when this query is given.
For a query of the third kind:
1 ≤ i ≤ 2 × 1 0 5 1 \leq i \leq 2 \times 10^5 1i2×105
Some boxes contain a card with the number i i i when this query is given.
At most 2 × 1 0 5 2 \times 10^5 2×105 numbers are to be reported.
All values in the input are integers.

Input

The input is given from Standard Input in the following format:
N N N
Q Q Q
q u e r y 1 \mathrm{query}_1 query1
q u e r y 2 \mathrm{query}_2 query2
⋮ \vdots
q u e r y Q \mathrm{query}_Q queryQ
Here, q u e r y q \mathrm{query}_q queryq denotes the q q q-th query, which is in one of the following formats:
1 1 1 i i i j j j
2 2 2 i i i
3 3 3 i i i

Output

Respond to the queries of the second and third kinds in order.

For each of those queries, print one line containing the elements to be reported in ascending order, with spaces in between.

Sample Input 1

5
8
1 1 1
1 2 4
1 1 4
2 4
1 1 4
2 4
3 1
3 2

Sample Output 1

1 2
1 1 2
1 4
4
Let us process the queries in order.
Write 1 1 1 on a card and put it into box 1 1 1.
Write 2 2 2 on a card and put it into box 4 4 4.
Write 1 1 1 on a card and put it into box 4 4 4.
Box 4 4 4 contains cards with the numbers 1 1 1 and 2 2 2.
Print 1 1 1 and 2 2 2 in this order.
Write 1 1 1 on a card and put it into box 4 4 4.
Box 4 4 4 contains cards with the numbers 1 1 1, 1 1 1, and 2 2 2.
Note that you should print 1 1 1 twice.
Boxes 1 1 1 and 4 4 4 contain a card with the number 1 1 1.
Note that you should print 4 4 4 only once, even though box 4 4 4 contains two cards with the number 1 1 1.
Boxes 4 4 4 contains a card with the number 2 2 2.

Sample Input 2

1
5
1 1 1
1 2 1
1 200000 1
2 1
3 200000

Sample Output 2

1 2 200000
1

思路

这道题我们可以用一个一维的vector(大小近乎相当于二维数组),来存储每个盒子里装的是什么,在进行操作二的时候,进行一次排序然后输出即可。之后我们可以用一个一维的set(大小近乎相当于二维数组)来存储这个数在哪几个盒子里(用set的原因:①题目中要求排序,set自带 ②题目中要求去重,set自带),然后每一次输出这个set就行

注意: 千万不能标记这个盒子是否出现这个数,这样时间复杂度会退化至 O ( N 2 ) O(N^2) O(N2),无法通过此题!

时间复杂度: O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n))

代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
#include <set>
#define endl '\n'
#define psb(i) push_back(i)
#define ppb() pop_back()
#define psf(i) push_front(i)
#define ppf() pop_front()
#define ps(i) push(i)
 
using namespace std;
 
typedef pair<int, int> PII;
 
const int N = 2e5 + 10;
 
int n, q;
int op, u, v;
vector<int> s[N];
set<int> has[N];
 
inline int read()
{
    int w = 1, s = 0;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-') w = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar();
    
    return w * s;
}
 
int main()
{
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);
    
    cin >> n >> q;
    
    while (q --)
    {
    	cin >> op;
    	if (op == 1)
    	{
    		cin >> u >> v;
    		s[v].push_back(u);
    		has[u].insert(v);
    	}
    	else if (op == 2)
    	{
    		cin >> v;
    		sort(s[v].begin(), s[v].end());
    		for (auto c : s[v])
    			cout << c << " ";
    		cout << endl;
    	}
    	else
    	{
    		cin >> u;
    		for (auto c : has[u])
    			cout << c << " ";
    			
    		cout << endl;
    	}
    }
    
    return 0;
}

D - Writing a Numeral

原题

Problem Statement

We have a string S S S. Initially, S = S= S= 1.

Process Q Q Q queries in the following formats in order.
1 x : Append a digit x x x at the end of S S S.
2 : Delete the digit at the beginning of S S S.
3 : Print the number represented by S S S in decimal, modulo 998244353 998244353 998244353.

Constraints

1 ≤ Q ≤ 6 × 1 0 5 1 \leq Q \leq 6 \times 10^5 1Q6×105
For each query in the first format, x ∈ { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 } x \in \{1,2,3,4,5,6,7,8,9\} x{1,2,3,4,5,6,7,8,9}.
A query in the second format is given only if S S S has a length of 2 2 2 or greater.
There is at least one query in the third format.

Input

The input is given from Standard Input in the following format:
Q Q Q
q u e r y 1 \mathrm{query}_1 query1
⋮ \vdots
q u e r y Q \mathrm{query}_Q queryQ
Here, q u e r y i \mathrm{query}_i queryi denotes the i i i-th query, which is in one of the following formats:
1 1 1 x x x
2 2 2
3 3 3

Output

Print q q q lines, where q q q is the number of queries in the third format. The i i i-th line ( 1 ≤ i ≤ q ) (1 \leq i \leq q) (1iq) should correspond to the i i i-th query in the third format.

Sample Input 1

3
3
1 2
3

Sample Output 1

1
12
In the first query, S S S is 1, so you should print 1 1 1 modulo 998244353 998244353 998244353, that is, 1 1 1.

In the second query, S S S becomes 12.

In the third query, S S S is 12, so you should print 12 12 12 modulo 998244353 998244353 998244353, that is, 12 12 12.

Sample Input 2

3
1 5
2
3

Sample Output 2

5

Sample Input 3

11
1 9
1 9
1 8
1 2
1 4
1 4
1 3
1 5
1 3
2
3

Sample Output 3

0
Be sure to print numbers modulo 998244353 998244353 998244353.

思路

M = 998244353 , a = S   m o d   M M = 998244353, a = S\: mod \: M M=998244353,a=SmodM

第一种操作:

设S后面加了 x x x
则: a = ( a × 10 + x ) % M a = (a\times 10 + x) \% M a=(a×10+x)%M
证明:
∵ a = S % M , S ′ = S × 10 + x , a ′ = S ′ % m ∴ a ′ = S ′ % m = ( s × 10 + x ) % m = ( S × 10 ) % M + x % m = S % M × 10 % M + x % M = a × 10 % M + x % M = ( a × 10 + x ) % M \begin{equation*} \begin{split} & \because a = S \% M, S' = S\times 10 + x,a' = S' \% m \\ & \therefore a' =S'\%m=(s\times10+x)\%m\\ & \qquad = (S\times 10) \% M + x \% m \\ & \qquad = S \% M \times 10 \% M + x \% M\\ & \qquad = a \times 10 \% M + x \% M\\ & \qquad = (a\times10 + x) \% M\\ \end{split} \end{equation*} a=S%M,S=S×10+x,a=S%ma=S%m=(s×10+x)%m=(S×10)%M+x%m=S%M×10%M+x%M=a×10%M+x%M=(a×10+x)%M

第二种操作

S = S 0 × 1 0 ∣ S ∣ − 1 + S ′ S = S_0\times 10^{|S|-1} + S' S=S0×10S1+S

证明:
∵ a = S % M , S ′ = S − S 0 × 1 0 ∣ S ∣ − 1 ∴ a ′ = S ′ % M = ( S − S 0 × 1 0 ∣ S ∣ − 1 ) % M = S % M − ( S 0 × 1 0 ∣ S ∣ − 1 ) % M = a − ( S 0 × 1 0 ∣ S ∣ − 1 ) % M \begin{equation*} \begin{split} & \because a = S \% M, S' = S - S_0\times 10^{|S|-1}\\ & \therefore a' = S' \% M = (S - S_0\times10^{|S| - 1})\% M\\ & \qquad = S \% M - (S_0\times10^{|S| - 1}) \% M\\ & \qquad = a - (S_0\times10^{|S| - 1}) \% M \end{split} \end{equation*} a=S%M,S=SS0×10S1a=S%M=(SS0×10S1)%M=S%M(S0×10S1)%M=a(S0×10S1)%M

注意: a − ( S 0 × 1 0 ∣ S ∣ − 1 ) a - (S_0\times10^{|S| - 1}) a(S0×10S1)有可能小于0,计算机算出的模数也会是个负的,事实上是个正的,所以我们只需在加M的基础上再模M就行,即: ( a + M − ( S 0 × 1 0 ∣ S ∣ − 1 ) ) % M (a + M - (S_0\times10^{|S| - 1})) \% M (a+M(S0×10S1))%M

第三种操作

直接输出a

代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <deque>
#define endl '\n'
#define psb(i) push_back(i)
#define ppb() pop_back()
#define psf(i) push_front(i)
#define ppf() pop_front()
#define ps(i) push(i)
 
using namespace std;
 
typedef pair<int, int> PII;
 
const int N = 8e5 + 10;
 
int q, op, num;
long long m10[N];
 
inline int read()
{
    int w = 1, s = 0;
    char c = getchar();
    while (c < '0' || c > '9')
    {
        if (c == '-') w = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar();
    
    return w * s;
}
string mod(string a,int b)//高精度a除以单精度b
{
    long long d = 0;
    for(int i = 0; i < a.size(); i ++) d = (d * 10 + (a[i] - '0')) % b;  //求出余数
    return to_string(d);
}
 
void init()
{
	string t = "1";
	int cnt = 6e5 + 10;
	
	int dig = 1;
	while (cnt --)
    {
		m10[dig ++] = stoll(t);
    	t += "0";
		t = mod(t, 998244353);
    }
}
 
int main()
{
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);
    
    init();
    
    deque<int> s;
    
    cin >> q;
    
    s.psb(1);
    
    long long tmp = 1;
    while (q --)
    {
    	cin >> op;
    	if (op == 1)
    	{
    		cin >> num;
    		s.psb(num);
    		tmp = (tmp * 10 + num) % 998244353;
    	}
    	else if (op == 2)
    	{
    		tmp = (tmp + 998244353 - ((long long)(s.front() * m10[s.size()]) % 998244353)) % 998244353;
    		s.ppf();
    	}
    	else
    		cout << tmp << endl;
    }
    
    return 0;
}

今天就到这里了!

大家有什么问题尽管提,我都会尽力回答的!

吾欲您伸手,点的小赞赞。吾欲您喜欢,点得小关注!

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值