Codeforces Round #632 (Div.2)

比赛链接 / 官方题解链接

紫名留念!

A. Little Artem

Solution

构造题,染色成棋盘,若 $n\times m$ 是偶数就再挑一个白色染成黑色即可。

Code

>folded
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include<bits/stdc++.h>

using namespace std;

template<typename T>void read(T&x){x=0;int fl=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')
fl=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}x*=fl;}
template<typename T,typename...Args>inline void read(T&t,Args&...args){read(t);read(args...);}

typedef long long LL;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define mp(x, y) make_pair(x, y)
#define pb(x) emplace_back(x)

int T, n, m;

int main(){
read(T);
while(T--){
read(n, m);
if((n * m) & 1){
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if((i + j) & 1) putchar('W');
else putchar('B');
}
puts("");
}
continue;
}
else{
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(i == 1 && j == 1){
putchar('B');
continue;
}
if((i + j) & 1) putchar('B');
else putchar('W');
}
puts("");
}
continue;
}
}
return 0;
}

B. Kind Anton

Solution

$\forall i\in[1,n]$:

  • 若 $a[i]<b[i]$,则必须 $\exists j\in[1,i-1] (a[j]=1)$;

  • 若 $a[i]>b[i]$,则必须 $\exists j\in[1,i-1] (a[j]=-1)$.

不满足上述条件输出 NO,满足输出 YES.

Code

>folded
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include<bits/stdc++.h>

using namespace std;

template<typename T>void read(T&x){x=0;int fl=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')
fl=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}x*=fl;}
template<typename T,typename...Args>inline void read(T&t,Args&...args){read(t);read(args...);}

typedef long long LL;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define mp(x, y) make_pair(x, y)
#define pb(x) emplace_back(x)

const int N = 100005;

int T, n;
LL a[N], b[N];
bool e[10];

int main(){
read(T);
while(T--){
read(n);
e[0] = e[1] = e[2] = 0;
for(int i = 1; i <= n; i++) read(a[i]);
for(int i = 1; i <= n; i++) read(b[i]);
bool ok = true;
for(int i = 1; i <= n; i++){
if(a[i] < b[i]){
if(!e[2]){
ok = false;
break;
}
}
else if(a[i] > b[i]){
if(!e[0]){
ok = false;
break;
}
}
e[a[i]+1] = 1;
}
puts(ok ? "YES" : "NO");
}
return 0;
}

C. Eugene and an array

Solution

求出前缀和,逆序枚举区间左端点,需要求出值与当前节点相同的节点最小位置,并且与最小的 $0$ 区间右端点取 $\min$,统计答案。

Code

>folded
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include<bits/stdc++.h>

using namespace std;

template<typename T>void read(T&x){x=0;int fl=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')
fl=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}x*=fl;}
template<typename T,typename...Args>inline void read(T&t,Args&...args){read(t);read(args...);}

typedef long long LL;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define mp(x, y) make_pair(x, y)
#define pb(x) emplace_back(x)

const int N = 200005;

int n;
LL a[N], s[N], ans, mnpos;
map<LL, LL> pos;

int main(){
read(n);
mnpos = n + 1;
for(int i = 1; i <= n; i++){
read(a[i]);
s[i] = s[i-1] + a[i];
}
for(int i = n; i >= 1; i--){
pos[s[i]] = i;
if(pos[s[i-1]] == 0) ans += mnpos - i;
else{
mnpos = min(mnpos, pos[s[i-1]]);
ans += mnpos - i;
}
}
printf("%lld\n", ans);
return 0;
}

D. Challenges in school №41

Solution

每个 $L$ 都会与它前面的所有 $R$ 交换一次,所以最大时间就是最多交换次数 $=\sum\limits_{s[i]==L}i之前R的数量$, 如果 $k$ 大于这个数无解;然后我们按最小时间的方案模拟过程,即每个时间把所有相邻的 $RL$ 都给交换了。如果 $k$ 小于最小时间则无解,否则,把同一时间进行的操作拆开补满 $k$ 比最小时间多出来的部分。

Code

>folded
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include<bits/stdc++.h>

using namespace std;

template<typename T>void read(T&x){x=0;int fl=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')
fl=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}x*=fl;}
template<typename T,typename...Args>inline void read(T&t,Args&...args){read(t);read(args...);}

typedef long long LL;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define mp(x, y) make_pair(x, y)
#define pb(x) emplace_back(x)

const int N = 3005;

int n, k, id;
char s[N];
LL maxk, mink;
vi v, ans[N*N];

int main(){
read(n, k);
scanf("%s", s+1);
LL cnt = 0;
for(int i = 1; i <= n; i++){
cnt += s[i] == 'R';
if(s[i] == 'L') maxk += cnt;
}
if(k > maxk) return puts("-1"), 0;
for(int i = 1; i < n; i++)
if(s[i] == 'R' && s[i+1] == 'L')
v.pb(i);
cnt = 0;
while(!v.empty()){
id++;
vi tmp;
while(!v.empty()){
int cur = v.back(); v.pop_back();
ans[id].pb(cur);
s[cur] = 'L', s[cur+1] = 'R';
if(s[cur+2] == 'L') tmp.pb(cur+1);
if(s[cur-1] == 'R') tmp.pb(cur-1);
}
while(!tmp.empty())
v.pb(tmp.back()), tmp.pop_back();
}
mink = id;
if(k < mink) return puts("-1"), 0;
k -= mink;
for(int i = 1; i <= id; i++){
while(k && !ans[i].empty()){
printf("1 %d\n", ans[i].back());
ans[i].pop_back();
if(!ans[i].empty()) k--;
}
if(!k && !ans[i].empty()){
printf("%d ", (int)ans[i].size());
for(auto t: ans[i]) printf("%d ", t);
puts("");
}
}
return 0;
}

E. Road to 1600

Solution

【参看dls的视频讲解吧~:链接

Code

>folded
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include<bits/stdc++.h>

using namespace std;

template<typename T>void read(T&x){x=0;int fl=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')
fl=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}x*=fl;}
template<typename T,typename...Args>inline void read(T&t,Args&...args){read(t);read(args...);}

typedef long long LL;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define mp(x, y) make_pair(x, y)
#define pb(x) emplace_back(x)

int n, tot, ans[505][505];

void solve(int m, int k){
if(m == 3){
ans[2][2] = ++tot, ans[2][3] = ++tot, ans[3][3] = ++tot;
ans[3][1] = ++tot, ans[2][1] = ++tot, ans[1][3] = ++tot;
ans[1][2] = ++tot, ans[1][1] = ++tot, ans[3][2] = ++tot;
return;
}
if(!k){
for(int i = 1; i <= m; i++) ans[m][i] = ++tot;
for(int i = m-1; i >= 1; i--) ans[i][m] = ++tot;
if(m == 4) swap(ans[1][m], ans[2][m]);
}
else{
for(int i = 1; i <= m; i++) ans[i][m] = ++tot;
for(int i = m-1; i >= 1; i--) ans[m][i] = ++tot;
if(m == 4) swap(ans[m][1], ans[m][2]);
}
solve(m - 1, k ^ 1);
}

int main(){
read(n);
if(n == 1 || n == 2) return puts("-1"), 0;
solve(n, 0);
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++)
printf("%d ", ans[i][j]);
puts("");
}
return 0;
}

F. Kate and imperfection

Solution

参考博客】首先把所有质数丢进集合,然后考虑加入合数,先加入与当前集合内的数的最大公因数为 $2$ 的所有合数,再加入最大公因数为 $3$ 的所有合数……于是每加入一个合数,答案就是其最大因数。处理出所有数的最大因数(质数为 $1$),排序后输出即可。

Code

>folded
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<bits/stdc++.h>

using namespace std;

template<typename T>void read(T&x){x=0;int fl=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')
fl=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}x*=fl;}
template<typename T,typename...Args>inline void read(T&t,Args&...args){read(t);read(args...);}

typedef long long LL;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define mp(x, y) make_pair(x, y)
#define pb(x) emplace_back(x)

const int N = 500005;

int n, ans[N];

int main(){
read(n);
for(int k = 2; k <= n; k++){
if(!ans[k]) ans[k] = 1;
for(int j = 2; k * j <= n; j++)
ans[k*j] = k;
}
sort(ans+2, ans+n+1);
for(int i = 2; i <= n; i++)
printf("%d ", ans[i]);
return 0;
}
作者

xyfJASON

发布于

2020-04-09

更新于

2020-12-20

许可协议

评论