Codeforces Round #632 (Div. 2) 题解
文章目录
A. Little Artem
-
题意
你需要绘制一个 n × m n\times m n×m的木板,木板中的单元格要么是白色要么是黑色的。现在定义 B B B的值为黑色单元格相邻的单元格至少有一个是白色的数量,同理 W W W的值定义为白色单元格相邻的单元格至少有一个是黑色的数量。你需要保证 B = W + 1 B=W+1 B=W+1。 -
解题思路
这种题一般需要针对性的解决,即对于任何的 n × m n\times m n×m都适用,我们试想,如果绘制一个白块,那么 W W W就一定为 1 1 1,我们需要让 B = 2 B=2 B=2,这也很好办,直接放到四个对角任意一个,那么与之相邻的黑块就有两个。符合要求。 -
AC代码
/**
*@filename:A
*@author: pursuit
*@created: 2021-08-10 18:18
**/
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int t,n,m;
void solve(){
for(int i = 1; i <= n; ++ i){
for(int j = 1; j <= m; ++ j){
if(i == n && j == m)cout << 'W';
else cout << 'B';
}
cout << endl;
}
}
int main(){
cin >> t;
while(t -- ){
cin >> n >> m;
solve();
}
return 0;
}
B. Kind Anton
-
题意
给你一个序列 a , b a,b a,b。其中 a a a的初始值只有 { − 1 , 0 , 1 } \{-1,0,1\} {−1,0,1},你可以选择 ( i , j ) (i,j) (i,j),其中 i < j i<j i<j。然后将 a i a_i ai加到 a j a_j aj上,需要你判断 a a a能否变成 b b b。 -
解题思路
显然,我们只要在进行操作之前我们想要的 1 , − 1 1,-1 1,−1,那么必然可行。即我们可以记录 1 1 1和 − 1 -1 −1是否出现过,然后遍历一遍数组,当需要用到的时候没有,那么此时必定不可行。至此题解。 -
AC代码
/**
*@filename:B
*@author: pursuit
*@created: 2021-08-10 18:35
**/
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int t,n,a[N],b[N];
void solve(){
bool flag = false;
int cnt1 = 0,cnt2 = 0;
for(int i = 1; i <= n; ++ i){
if(a[i] == b[i]){
}
else if(a[i] < b[i] && cnt1 == 0){
flag = true;
break;
}
else if(a[i] > b[i] && cnt2 == 0){
flag = true;
break;
}
if(a[i] == 1)cnt1 ++;
else if(a[i] == -1)cnt2 ++;
}
if(flag){
cout << "NO" << endl;
}
else{
cout << "YES" << endl;
}
}
int main(){
cin >> t;
while(t -- ){
cin >> n;
for(int i = 1; i <= n; ++ i){
cin >> a[i];
}
for(int i = 1; i <= n; ++ i){
cin >> b[i];
}
solve();
}
return 0;
}
C. Eugene and an array
-
题意
给你一个数组,需要你找到非空好子数组的数量。其中好子数组定义为:其任意子数组元素总和不为 0 0 0。 -
解题思路
由前缀和易知,如果一段区间 [ l , r ] [l,r] [l,r]为 0 0 0,那么 s u m [ r ] − s u m [ l − 1 ] = 0 sum[r] - sum[l-1]=0 sum[r]−sum[l−1]=0,所以我们可以利用记录前缀和的位置 i i i,那么在过程中维护区间和不为 0 0 0的长度即可,累加符合区间数量即可。 -
AC代码
/**
*@filename:C
*@author: pursuit
*@created: 2021-08-10 18:45
**/
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 2e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int n,a[N];
map<ll,int> p;
void solve(){
ll ans = 0, sum = 0;
int pos = -1;//为最早不好的。
p[0] = 0;
for(int i = 1; i <= n; ++ i){
sum += a[i];
if(p.count(sum)){
pos = max(pos,p[sum]);
}
ans += i - (pos + 1);
p[sum] = i;
}
cout << ans << endl;
}
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; ++ i){
scanf("%d", &a[i]);
}
solve();
return 0;
}
D. Challenges in school №41
-
题意
给定序列求使得转身 k k k轮刚好序列中不再存在转身的序列的解决方案。 -
解题思路
我们可以将每一轮左转的人存储起来。然后判断轮数够不够,如果不够,判断我们能不能分解构成 k k k轮。最后输出解决方案的时候要注意每一轮每一轮输出,注意按顺序填充我们的轮次。 -
AC代码
/**
*@filename:D
*@author: pursuit
*@created: 2021-08-11 10:22
**/
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int n,k,a[N];
char s[N];
vector<vector<int> > ans;
void solve(){
//将每轮左转的存入数组中。
int sum = 0;
while(true){
vector<int> now;
for(int i = 1; i < n; ++ i){
if(a[i] && !a[i + 1]){
now.push_back(i);
//debug(i);
swap(a[i],a[i + 1]);
i ++;
}
}
//判断是否还存在转身的。
if(now.empty())break;
sum += now.size();//转身对数。
ans.push_back(now);
}
//由于需要使得序列中转身k轮后且恰好不出现转身的序列。
//若sum > k我们可以填充。
if(ans.size() > k || sum < k){
puts("-1");
}
else{
int res = k - ans.size();//需要填充的轮次。
for(auto now : ans){
while(now.size() > 1 && res > 0){
printf("1 %d\n", now.back());
now.pop_back();
res --;
}
printf("%d ", now.size());
for(auto x : now){
printf("%d ", x);
}
puts("");
}
}
}
int main(){
scanf("%d%d", &n, &k);
scanf("%s", s + 1);
for(int i = 1; i <= n; ++ i){
if(s[i] == 'R')a[i] = 1;
}
solve();
return 0;
}
E. Road to 1600
-
题意
找到一种方案,使得车花费比皇后的花费要多。 -
解题思路
显然,当 n < 3 n < 3 n<3时是不存在的,因为皇后畅通无阻,试想,当 n = 3 n=3 n=3时,我们可以手撕一种方案,注意我们需要让 1 1 1在边界。这样我们就可以将 1 1 1看成入口,然后对于 n > 3 n>3 n>3的时候,环该方案构造即可。

-
AC代码
/**
*@filename:E
*@author: pursuit
*@created: 2021-08-11 10:58
**/
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 500 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
//找到3 * 3矩阵的特例,再从1入口进去即可。
int n,res[N][N];
void solve(){
if(n <= 2){
puts("-1");
}
else{
res[1][1] = 9,res[1][2] = 5,res[1][3] = 6;
res[2][1] = 7,res[2][2] = 2,res[2][3] = 8;
res[3][1] = 1,res[3][2] = 3,res[3][3] = 4;
int t = n,num = 0;//num为编号。
while(t > 3){
if(t % 2 == 0){
for(int i = 1; i <= t; ++ i){
res[i][t] = ++ num;
}
for(int j = t - 1; j >= 1; -- j){
res[t][j] = ++ num;
}
}
else{
for(int j = 1; j <= t; ++ j){
res[t][j] = ++ num;
}
for(int i = t - 1; i >= 1; -- i){
res[i][t] = ++ num;
}
}
t --;
}
//最后编号为num。
for(int i = 1; i <= n; ++ i){
for(int j = 1; j <= n; ++ j){
if(i <= 3 && j <= 3)res[i][j] += num;
printf("%d ", res[i][j]);
}
puts("");
}
}
}
int main(){
scanf("%d", &n);
solve();
return 0;
}
F. Kate and imperfection
-
题意
求当 k = [ 2 , n ] k=[2,n] k=[2,n]时, k k k为 a a a序列大小,使得 a a a序列中任意两元素的 g c d gcd gcd最大值最小。 -
解题思路
我们自然是想将质数的放入进去,然后再按除本身的最大因子从小到达放入即可达到最优。那么只需要记录每个数的次大因子,当该数放入时,结果就为 它 它 它。 -
AC代码
/**
*@filename:F
*@author: pursuit
*@created: 2021-08-11 10:42
**/
#include <bits/stdc++.h>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;
int n;
void solve(){
vector<int> ans(n + 1,1);//先定义所有的因子都为1.
for(int i = 2; i <= n; ++ i){
for(int j = i * 2; j <= n; j += i){
//将i的倍数都找出来。
ans[j] = i;
}
}
sort(ans.begin(),ans.end());
for(int i = 2; i <= n; ++ i){
printf("%d%c", ans[i], i == n ? '\n' : ' ');
}
}
int main(){
scanf("%d", &n);
solve();
return 0;
}

浙公网安备 33010602011771号